﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Custom Data Service Providers</title>

<style type="text/css">

table
	{
	margin-left:.25in;
	margin-right:.25in;
	}

div.Code
	{
	margin-left:.2in;
	background:#EFF3FF;
	font-size:8.0pt;
	font-family:Consolas;
	}

div.Code p
	{
	margin-top:0pt;
	margin-bottom:0pt;
	}


.codeKeyword
	{
	color: blue;
	}

.codeType
	{
	color: #2B91AF;
	}

.codeComment
	{
	color: green;
	}

.codeString
	{
	color: #A31515;
	}


</style>

</head>

<body>

<h1>Custom Data Service Providers</h1>
<p>If you have decided that working with Microsoft’s WCF Data Services Framework is the best 
means to create a data service that supports OData, the next step is to 
determine whether you can use one of the framework’s built-in Data Service 
Providers or if you need to implement your own.</p>
<p> Note: using a 
custom data service provider requires the 
<a href="http://www.microsoft.com/downloads/details.aspx?familyid=79d7f6f8-d6e9-4b8c-8640-17f89452148e&amp;displaylang=en" title="Data Services Update for .NET Framework 3.5 SP1">
WCF (ADO.NET) Data Services Update for .NET Framework 3.5 SP1</a> released in 
February 2010 or the .NET Framework version 4.</p>
<p></p>
<h2>What is a Data Service Provider?</h2>
<p>
A Data Service Provider is simply a .NET class that sits between the Data Services Framework 
and the underlying data source that’s being exposed. At a minimum, this class 
should implement the <i>
IDataServiceQueryProvider</i> and <i>
IDataServiceMetadataProvider</i> interfaces, which provide the basis for a 
read-only service; it generally also implements
<i>IServiceProvider </i>through which the 
data services framework hooks everything together.</p>
<p>
Optionally, the 
provider may also implement <i>IDataServiceUpdateProvider</i>, <i>IDataServicePagingProvider</i>, and 
<i>IDataServiceStreamProvider</i>. The purpose of all these are described in Table 
1. (Note: the links given here for these interfaces point to the .NET Framework 
4 documentation but these also exist in the Data Services Update for .NET 
Framework 3.5 SP1.)</p>

<table style="width: 100%">
	<tr>
		<td style="width: 267px"><strong>Interface</strong></td>
		<td><strong>Use by WCF Data Services Framework</strong></td>
	</tr>
	<tr>
		<td style="width: 267px">
			<p><a href="http://msdn.microsoft.com/en-us/library/system.iserviceprovider.aspx"><i>IServiceProvider</i></a></p>
		</td>
		<td>
			<p>Informs the framework that the class is an appropriate service.</p>
		</td>
	</tr>
	<tr>
		<td style="width: 267px">
		<p>
			<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataservicequeryprovider(VS.100).aspx">
			<i>IDataServiceQueryProvider</i></a></p>
		</td>
		<td> Use in conjunction with all HTTP GET, PUT, POST, and DELETE 
		requests.</td>
	</tr>
	<tr>
		<td style="width: 267px">
			<p><a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataservicemetadataprovider(VS.100).aspx">
			<i>IDataServiceMetadataProvider</i></a></p>
		</td>
		<td> Used to reason 
		about available ResourceTypes, Properties, Keys, NavigationProperties, 
		and ResourceSets.</td>
	</tr>
	<tr>
		<td style="width: 267px">
		<p>
			<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataserviceupdateprovider(VS.100).aspx">
			<i>IDataServiceUpdateProvider</i></a></p>
		</td>
		<td> Used to fulfill HTTP PUT, POST, and DELETE requests.</td>
	</tr>
	<tr>
		<td style="width: 267px">
		<p>
			<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataservicepagingprovider(VS.100).aspx">
			<i>IDataServicePagingProvider</i></a></p>
		</td>
		<td> Allows fine-grained control over server-driven paging.</td>
	</tr>
	<tr>
		<td style="width: 267px">
		<p>
			<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataservicestreamprovider(VS.100).aspx">
			<i>IDataServiceStreamProvider</i></a></p>
		</td>
		<td>
			Used to manipulate an underlying stream for Media Link Entries.
		</td>
	</tr>
</table>

<p align="center">Table 1: Interfaces implemented by a custom provider. Note that all of the
<i>IDataService*</i> interfaces are defined in the <a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers(VS.100).aspx">
System.Data.Services.Providers</a> namespace;
<i>IServiceProvider</i> is defined in the <a href="http://msdn.microsoft.com/en-us/library/system.aspx">
System</a> namespace.</p>
<p>To fulfill its end 
of the bargain, the provider internally utilizes objects in the data store (or 
representing the data store) that implement the
<a href="http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx">
<i>
IQueryable</i></a> interface (found in the <a href="http://msdn.microsoft.com/en-us/library/system.linq.aspx">
System.Linq</a> namespace).</p>

<p>
Overall, these relationships are illustrated in Figure 1.</p>
<p align="center">
<img alt="WCF Data Services and Data Service Providers" height="558" src="assets/Figure1.png" width="1424" />&nbsp;</p>
<p align="center">
Figure 1: The WCF Data Services Framework interacts with a data source through a 
data service provider. The provider is a .NET class that implements <i>IServiceProvider</i>, <i>
IDataServiceQueryProvider </i>and <i>IDataServiceMetadataProvider</i>, and optionally
<i>IDataServiceUpdateProvider, IDataServicePagingProvider,</i> and <i>IDataServiceStreamProvider</i>. 
The provider can be directly part of the data source, if desired.</p>

<h2>Existing/Built-In Providers</h2>
<p>A quick look at Figure 1 should convince you that 
implementing a full data service provider is a non-trivial investment, as we’ll 
see in this document. Let’s then take a quick look at providers that already 
exist so you can understand if they can be utilized in your particular scenario. 
(See <a href="http://msdn.microsoft.com/en-us/library/dd672591(VS.100).aspx">http://msdn.microsoft.com/en-us/library/dd672591(VS.100).aspx</a> for 
documentation on these providers.)</p>
<h3>Entity Data Model/ADO.NET Entity Framework</h3>
<p>
If you are already 
employing the ADO.NET Entity Framework to create a data access layer to a source 
(for which there is already an ADO.NET data provider), the Data Services 
Framework can use your Entity Data Model. Simply derive your specific data 
service class from <i>DataService&lt;T&gt;</i> 
where <i>T</i> is your strongly-typed
<i>ObjectContext</i> from the Entity 
Framework, and you’re done.</p>
<p>For example, if
<i>NorthwindEntities</i> is the name of your 
Entity Framework <i>ObjectContext</i> class, 
then you would define a <i>
NorthwindDataService</i> class as follows:</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
class</span> <span class="codeType">
NorthwindDataService</span> :
<span class="codeType">
DataService&lt;NorthwindEntities&gt;</span></p>
</div>


<p>For more details on this provider, see
<a href="http://msdn.microsoft.com/en-us/library/dd673932(VS.100).aspx">
http://msdn.microsoft.com/en-us/library/dd673932(VS.100).aspx</a>.</p>

<h3>Reflection Provider</h3>
<p>If you have your 
own class that represents a data source and it has a number of strongly-typed
<i>IQueryable</i> properties, you can use the 
built-in <a href="http://msdn.microsoft.com/en-us/library/dd723653(VS.100).aspx">reflection provider</a> to turn it into a 
read-only service. For example, the following class has two queryable 
properties, <i>Products</i> and <i>Categories</i>:</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
class</span> <span class="codeType">MyDataSource</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span>
<span class="codeType">IQueryable&lt;Product&gt;</span>
<span class="codeType">Products</span> {
<span class="codeKeyword">get</span> {...} }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span>
<span class="codeType">IQueryable&lt;Categories&gt;</span>
<span class="codeType">Categories</span> {
<span class="codeKeyword">get</span> {...} }</p>
<p>}</p>
</div>

<p>
With this, the built-in reflection provider will infer resource sets, types, and properties 
automatically. This is best when you have static classes that are defined at 
runtime or are defined by a typed ADO.NET DataSet.</p>
<p> When using the reflection provider, you can also make the data source read-write by extending 
your data source class to implement <i>IUpdatable </i>(as shown in Figure 1):</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
class</span> <span class="codeType">MyDataSource
</span> : <span class="codeType">IUpdatable</span></p>
</div>
<p>
As useful as this approach is, there are some limitations that might disqualify it for your 
particular scenario:</p>
<ol>
	<li>It is static: the shape of the 
	service cannot evolve over time.</li>
	<li>It needs CLR classes for each 
	ResourceType, which you might not have.</li>
	<li>It needs to find ID or {Type}ID 
	properties to use as keys. This requires use of the [DataServiceKey(...)] 
	attribute.</li>
	<li>It blindly exposes all public 
	properties of the CLR classes.</li>
	<li>You can’t take advantage of 
	advanced features like Open Types, which allows resources to optionally 
	include more <a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataservicequeryprovider.getopenpropertyvalue(VS.100).aspx">
	Open Properties</a>.</li>
	<li>You have less control; for example, you can&#39;t log requests as easily or modify metadata or rename 
	properties.</li>
</ol>
<p>If any of these limitations are a problem, then a custom provider is necessary.</p>

<h3>LINQ to SQL</h3>
<p>If you want to 
create a data service over a LINQ to SQL data source, take a look at the 
<a href="http://code.msdn.microsoft.com/IUpdateableLinqToSql">
IUpdatable Implementation for LINQ to SQL</a> on MSDN CodeGallery. This sample shows how to extend a strongly-typed
<i>DataContext</i> class to implement
<i>IUpdatable</i>. In conjunction with the 
reflection provider described above, you can then use this
<i>DataContext </i>just as if it were an Entity Framework
<i>ObjectContext</i>:</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
class</span> <span class="codeType">
NorthwindDataService </span>:
<span class="codeType">
DataService&lt;NorthwindDataContext&gt;</span></p>
</div>

<h2>Typed vs. Untyped Data Providers</h2>
<p>Though it is a non-trivial task, implementing a custom data 
provider is essential for data sources that don’t fit the standard molds covered 
by the other options above (a good example is SharePoint 2010). The remaining 
sections in this article will guide you through the process, starting with a 
read-only service and incrementally adding optional features.</p>
<p>There are two main varieties of providers that we’ll cover 
here. The first, covered in Parts 1-3, is a “typed” data provider, which is 
backed by specific CLR classes for each type of resource that the provider 
exposes. An “untyped” provider, on the other hand is necessary when specific 
backing CLR classes don’t exist (as when working with a database, though 
general-purpose classes, such as a <i>Dictionary</i>, might be used in an untyped provider). We’ll cover specific 
considerations for untyped providers in Parts 4 and 5 based on the discussion of 
typed providers in Parts 1-3.</p>

<p>Besides not needing individual classes for each resource 
type, there are a few things that are easier to do in untyped providers:</p>
<ol>
	<li>Resource 
	types can change at runtime (such as adding a new property to the resource); 
	it’s not necessary to recompile or restart the service. This means you can 
	also dynamically evolve your data model to expose more resource types and 
	data sets as they become available.</li>
	<li>You can store a pointer to the metadata for the resource type directly in the 
	resource type itself.</li>
	<li>You can store extra data along with a resource very easily, which potentially allows 
	you to take advantage of the WCF Data Services Framework’s support for 
	OpenTypes and
	<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataservicequeryprovider.getopenpropertyvalue(VS.100).aspx">Open Properties</a>.</li>
</ol>

<p>At present, this document does not cover the above features, 
nor does it cover server-side paging (<i>IDataServicePagingProvider</i>)<i>
</i>or streaming media (<i>IDataServiceStreamProvider</i>). 
For details on these, see the links in the Going Further section at the end.</p>

<h2>Part 1: Creating a Basic Typed Data Service Provider</h2>
<p>If you’d like to start first by looking at some code before we discuss it, we’ll be working with the series 
of samples that accompany this document in the Data Service Provider Toolkit. 
Each sample has the same structure but implements different feature levels as 
implied by the folder in which the sample lives: Typed\RO, Typed\RW, 
Typed\RWNavProp, UnTyped\RO, and Untyped\RW. We&#39;ll refer to specific samples by 
these folder names, and start here by looking at the projects in 
the Typed\RO folder:</p>
<ul>
	<li><strong>ODataDemo</strong> 
is a small demonstration data service that works with a small in-memory data 
source:
	<ul>
		<li>The in-memory data source is specifically 
composed of three instances of the <em>ProductEntity</em> class.
		</li>
		<li>The main data service class is
		<em>DemoDSPDataService</em> which is derived 
from <em>DSPDataService&lt;DSPContext&gt;</em> where
<em>DSPDataService </em>is the custom provider 
class (see below) and <em>DSPContext </em>holds the data.
		</li>
		<li>This data service only has three methods in its 
implementation:
		<ul>
			<li>
			<i>CreateDataSource</i> instantiates the in-memory
<i>ProductEntity</i> objects.
			</li>
			<li>
			<i>CreateDSPMetadata</i> is an implementation of an abstract method defined in the 
custom provider to initialize the service’s metadata.
			</li>
			<li>
			<i>InitializeService </i>sets up access rules and other service-wide behaviors, as 
all data services do in this method.
			<br />
			<br />
			</li>
		</ul>
		</li>
	</ul>
	</li>
	<li><b>DataServiceProvider</b> is the implementation of the custom provider:<ul>
		<li>DSPDataService.cs contains the implementation of 
the <i>DSPDataService</i> class from which 
the actual instance of the data service is derived (see above). It’s derived from
<i>DataService&lt;T&gt;</i>, a base class provided 
by the WCF Data Services Framework. It also implements
<i>IServiceProvider</i> and contains two 
private objects, <i>DSPMetadata</i> and
<i>DSPResourceQueryProvider</i> that supply 
the other interfaces for a basic read-only service (see below).</li>
		<li>DSPMetadata.cs contains the implementation of the
<i>DSPMetadata</i> class, which implements
<i>IDataServiceMetadataProvider</i>.</li>
		<li>DSPResourceQueryProvider.cs contains the 
implementation of the <i>DSPResourceQueryProvider </i>class, which implements
<i>IDataServiceQueryProvider</i>.</li>
		<li>DSPContext.cs contains the
<i>DSPContext</i> class, which holds the actual data reported through the 
provider. It’s implemented as a simple dictionary.</li>
		<li>ResourceTypeAnnotations.cs and 
ResourcePropertyAnnotations.cs contain helper classes.<br />
		<br />
		</li>
	</ul>
	</li>
	<li><strong>DSPTest</strong> is a test project for the data service using 
	the custom provider. You can run these tests in Visual Studio using the Test 
	| Run | All Tests in Solution menu command. The code in these projects will 
	give good examples of different requests that exercise the features of 
	the data service.</li>
</ul>

<p>We’ll start first by looking at the
<i>IServiceProvider</i> implementation, then those classes/interfaces for a 
read-only service, then the other interfaces that add optional features.</p>

<h3>IServiceProvider</h3>
<p>

When the WCF Data Services Framework first takes a request, it of course needs 
to ensure that the service to which that request has been directed (in the URL) 
is, in fact, a suitable data service. It does so by looking for the
<i>IServiceProvider </i>interface and using 
its <i>GetService </i>method to locate the 
implementations of <i>IDataServiceMetadataProvider </i>and <i>
IDataServiceQueryProvider</i>.</p>

<p>The following code is the implementation for this found in DSPDataService.cs 
(DataServiceProvider project):</p>

<div class="Code">

<p><span class="codeKeyword">public</span> <span class="codeKeyword">
abstract</span> <span class="codeKeyword">class</span>
<span class="codeType">DSPDataService</span>&lt;T&gt; :
<span class="codeType">DataService</span>&lt;T&gt;,
<span class="codeType">IServiceProvider</span> <span class="codeKeyword">where</span> 
T : <span class="codeType">DSPContext</span></p>
<p>{<br />
&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span>
<span class="codeKeyword">object</span> GetService(<span class="codeKeyword">Type</span> 
serviceType)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if </span>(serviceType ==
<span class="codeKeyword">typeof</span>(<span class="codeType">IDataServiceMetadataProvider</span>))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Note that we&#39;re calling the property Metadata here so that the 
metadata gets initialized the first</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// time it&#39;s accessed.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this.</span>Metadata;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">else if</span> (serviceType ==
<span class="codeKeyword">typeof</span>(<span class="codeType">IDataServiceQueryProvider</span>))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this.</span>resourceQueryProvider;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">else</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">null</span>;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>}</p>
</div>


<p>
How this method actually works depends upon your specific implementation, of 
course, but you can see the basics here nonetheless.</p>
<p>As noted before, the actual data service class in this project—the data service 
that is part of the overall web application defined by the solution—is derived 
from <i>DSPDataService&lt;T&gt;</i> as seen in the 
DemoDSPDataService.svc.cs file of the ODataDemoService project. A data service 
that does not employ a custom provider would otherwise be derived from the 
standard <i>DataService&lt;T&gt;</i> class provided 
by the framework.</p>
<p>It&#39;s important to also note that if WCF Data Services framework fails to find
<em>IServiceProvider</em> through the above process, it will also look for it 
directly on the data source directly, that is, on the class represented by <em>T</em>. 
This is another way of saying that the data source can be the provider as well 
(merging those two pieces as shown in Figure 2).</p>

<h3>The Data Source</h3>
<p>In our sample, the <i>DSPContext</i> class is 
the actual data source that the custom provider is working with, that is, it’s 
the data type that we use with the various &lt;T&gt;’s. As such it can be called 
anything, and can be derived from anything.</p>
<p>Note that we’re using this data source in a strongly-typed way by adding a 
generic constraint to the definition of the provider class, specifically the
<i>where T : DSPContext</i> at the end:</p>
<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
abstract</span> <span class="codeKeyword">class</span>
<span class="codeType">DSPDataService</span>&lt;T&gt; :
<span class="codeType">DataService</span>&lt;T&gt;,
<span class="codeType">IServiceProvider</span> <span class="codeKeyword">where</span> 
T : <span class="codeType">DSPContext</span></p>
</div>

<p>If the data source is fixed, however, and you don’t need a strongly-typed 
sub-class, then you wouldn’t need that constraint:</p>
<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
class</span> <span class="codeType">DSPDataService
</span>: <span class="codeType">DataService</span>&lt;<span class="codeType">MyDataSource</span>&gt;,
&nbsp;<span class="codeType">IServiceProvider</span></p>
</div>

<h3>IDataServiceMetadataProvider</h3>
<p>The next step is to provide the implementation of <i>IDataServiceMetadataProvider</i>, which is 
responsible for describing the shape or “model” of the information in your data source. This 
metadata is surfaced in the form of 
<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.resourcetype(VS.100).aspx">
<i>ResourceType</i></a>,
<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.resourceproperty(VS.100).aspx">
<i>ResourceProperty</i></a>,
<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.serviceoperation(VS.100).aspx">
<i>ServiceOperation</i></a>,
<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.resourceset(VS.100).aspx">
<i>ResourceSet</i></a> and 
<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.resourceassociationset(VS.100).aspx">
<i>ResourceAssociationSet</i></a> instances, all of which are public classes in the System.Data.Services.Providers 
namespace. You use these to build the metadata that’s returned through the 
methods of the interface.</p>

<p>How you implement those methods and construct the metadata 
depends on the nature of the data source. Your data might be static, in which 
case the metadata can be built once and returned whenever it’s requested. Or you 
might be dealing with completely dynamic data such that you’re creating the 
metadata from scratch every time (an obvious trade-off between flexibility and 
performance). It doesn’t really matter so long as you serve 
up the appropriate metadata.</p>

<p>The methods in the interface essentially just expose 
different aspects of the metadata. While the interface contains six methods and 
five properties, the basic (starter) implementation is fairly straightforward as 
we can see in the Typed\RO sample.</p>

<p>To look at the highlights of that sample, let’s first look 
back to the implementation of <i>IServiceProvider.GetService</i> that we saw earlier. When asked for
<i>IDataServiceMetadataProvider</i> it simply returns an instance of DSPMetadata, which implements that interface and manages 
the metadata. For this purpose it contains two private <i>Dictionary </i>instances called
<i>resourceSets</i> and <i>resourceTypes; </i>for the most part the methods and properties of the 
interface are only a few lines each:<i></i></p>



<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
class</span> <span class="codeType">DSPMetadata</span> 
: <span class="codeType">
IDataServiceMetadataProvider</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeType">
Dictionary</span>&lt;<span class="codeKeyword">string</span>,
<span class="codeType">ResourceSet</span>&gt; ResourceSets;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeType">
Dictionary</span>&lt;<span class="codeKeyword">string</span>,
<span class="codeType">ResourceType</span>&gt; resourceTypes;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeKeyword">string</span> containerName;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeKeyword">string</span> namespaceName;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">
DSPMetadata</span>(<span class="codeKeyword">string</span> containerName,
<span class="codeKeyword">string</span> namespaceName)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>ResourceSets =
<span class="codeKeyword">new</span>
<span class="codeType">Dictionary</span>&lt;string,
<span class="codeType">ResourceSet</span>&gt;();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>resourceTypes =
<span class="codeKeyword">new</span>
<span class="codeType">Dictionary</span>&lt;<span class="codeKeyword">string</span>,
<span class="codeType">ResourceType</span>&gt;();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>containerName = containerName;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>namespaceName = namespaceName;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Marks the metadata as read-only.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">internal</span> <span class="codeKeyword">void</span> SetReadOnly()</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">foreach</span> (<span class="codeKeyword">var</span> 
type <span class="codeKeyword">in</span> <span class="codeKeyword">this.</span>resourceTypes.Values)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type.SetReadOnly();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">foreach</span> (<span class="codeKeyword">var</span> 
set <span class="codeKeyword">in</span> <span class="codeKeyword">this.</span>ResourceSets.Values)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set.SetReadOnly();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// IDataServiceMetadataProvider members</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">string</span> ContainerName</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">get</span> { <span class="codeKeyword">return</span>
<span class="codeKeyword">this.</span>containerName; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">string</span> ContainerNamespace</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">get</span> { <span class="codeKeyword">return</span>
<span class="codeKeyword">this.</span>namespaceName; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">
System.Collections.Generic.IEnumerable</span>&lt;<span class="codeType">ResourceType</span>&gt; 
GetDerivedTypes(<span class="codeType">ResourceType</span> 
resourceType)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// We don&#39;t support type inheritance yet</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">new</span>
<span class="codeType">ResourceType</span>[0];</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">
ResourceAssociationSet</span> GetResourceAssociationSet(<span class="codeType">ResourceSet</span> 
ResourceSet, <span class="codeType">ResourceType</span> 
resourceType,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceProperty</span> resourceProperty)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span>
<span class="codeKeyword">new</span> <span class="codeType">
NotImplementedException</span>(<span class="codeString">&quot;Should never get 
here, reference properties are not yet supported.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">bool</span> HasDerivedTypes(<span class="codeType">ResourceType</span> 
resourceType)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
	<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="codeComment">// We don&#39;t support type inheritance yet</span>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">false</span>;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> 
System.Collections.Generic.<span class="codeType">IEnumerable</span>&lt;<span class="codeType">ResourceSet</span>&gt; 
resourceSets</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">get</span> { <span class="codeKeyword">return</span>
<span class="codeKeyword">this.</span>resourceSets.Values; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> 
System.Collections.Generic.<span class="codeType">IEnumerable</span>&lt;<span class="codeType">ServiceOperation</span>&gt; 
serviceOperations</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">get</span> { <span class="codeKeyword">return</span>
<span class="codeKeyword">new</span> serviceOperations[0]; 
}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">bool</span> TryResolveResourceSet(<span class="codeKeyword">string</span> 
name, <span class="codeKeyword">out</span> <span class="codeType">
ResourceSet</span> resourceSet)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this.</span>ResourceSets.TryGetValue(name,
<span class="codeKeyword">out</span> resourceSet); 
;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">bool</span> TryResolveResourceType(<span class="codeKeyword">string</span> 
name, <span class="codeKeyword">out</span> <span class="codeType">
ResourceType</span> resourceType)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this.</span>resourceTypes.TryGetValue(name,
<span class="codeKeyword">out</span> resourceType);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">bool</span> 
TryResolveServiceOperation(<span class="codeKeyword">string</span> name,
<span class="codeKeyword">out</span> <span class="codeType">ServiceOperation</span> 
serviceOperation)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// No service operations are supported yet</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;serviceOperation = <span class="codeKeyword">null</span>;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">false</span>;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">
System.Collections.Generic.IEnumerable</span>&lt;<span class="codeType">ResourceType</span>&gt; 
Types</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">get</span> { <span class="codeKeyword">return</span>
<span class="codeKeyword">this.</span>resourceTypes.Values; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>}</p>

</div>


<p>The other methods within <i>DSPMetadata</i> are internal helper functions to populate the
<i>resourceSets</i> and <i>resourceTypes</i>. The populating itself 
happens through some interaction between the data service and the provider. If 
you remember from earlier, the provider (the <i>DSPDataService&lt;T&gt;</i> class) defined an abstract method called
<i>CreateDSPMetadata</i> that’s implemented within <i>DemoDSPDataService</i>. Here’s that 
code:</p>

<div class="Code">
<p><span class="codeComment">//From DSPDataService.cs in the DataServiceProvider project</span></p>
<p><span class="codeKeyword">public</span> <span class="codeKeyword">abstract</span> <span class="codeKeyword">class</span>
<span class="codeType">DSPDataService</span>&lt;T&gt; :
<span class="codeType">DataService</span>&lt;T&gt;, <span class="codeType">
IServiceProvider</span> <span class="codeKeyword">where</span> T :
<span class="codeType">DSPContext</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span>
<span class="codeType">DSPMetadata</span> metadata;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">protected abstract </span><span class="codeType">DSPMetadata</span> 
CreateDSPMetadata();</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">protected</span> <span class="codeType">DSPMetadata</span> Metadata</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">get</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (<span class="codeKeyword">this.</span>metadata 
== <span class="codeKeyword">null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>metadata = CreateDSPMetadata();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>metadata.SetReadOnly();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>resourceQueryProvider =
<span class="codeKeyword">new</span> DSPResourceQueryProvider(<span class="codeKeyword">this.</span>metadata);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this.</span>metadata;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>...</p>
<p>&nbsp;</p>
<p>}</p>
<p>&nbsp;</p>
<p>...</p>
<p>&nbsp;</p>
<p><span class="codeComment">//From DemoDSPDataService.cs in the ODataDemoService 
project, within the DemoDSPDataService class</span></p>
<p>&nbsp;</p>
<p><span class="codeKeyword">protected override</span>
<span class="codeType">DSPMetadata</span> CreateDSPMetadata()</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">DSPMetadata</span> metadata = <span class="codeKeyword">new</span>
<span class="codeType">DSPMetadata</span><span class="codeString">(&quot;DemoService&quot;</span>,
<span class="codeString">&quot;DataServiceProviderDemo&quot;</span>);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Rename the type to &quot;Product&quot;</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> product = metadata.AddEntityType(typeof(<span class="codeType">ProductEntity</span>),
<span class="codeString">&quot;Product&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddKeyProperty(product, <span class="codeString">&quot;ID&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(product, <span class="codeString">&quot;Name&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(product, <span class="codeString">&quot;Description&quot;</span>);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// By not adding the Price property to metadata we&#39;re hiding it from the users 
of the service,</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// there&#39;s no way users can even know that such property exists, let alone get 
its value.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(product, <span class="codeString">&quot;ReleaseDate&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(product, <span class="codeString">
&quot;DiscontinueDate&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(product, <span class="codeString">&quot;Rating&quot;</span>);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddResourceSet<span class="codeString">(&quot;Products&quot;</span>, product);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> metadata;</p>
<p>}</p>
</div>

<p>The methods being called on the <i>metadata</i> variable are the helper functions defined in
<i>DSPMetadata</i>. They basically create <i>ResourceType, ResourceTypeKind, ResourceProperty , ResourcePropertyKind, </i>and
<i>ResourceSet</i> instances as needed. As you can see, all this is building up a description of the
<i>ProductEntity </i>type of which our actual data is composed:</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
class</span> <span class="codeType">ProductEntity</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">int</span> ID {
<span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">string</span> Name {
<span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">string</span> Description {
<span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">double</span> Price {
<span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">DateTime</span> ReleaseDate {
<span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">DateTime</span>? DiscontinueDate 
{ <span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">int</span> Rating {
<span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; }</p>
<p>}</p>
</div>

<p>What’s most important to note here is that it’s not necessary to expose 
everything in the metadata. Properties that should remain private—like
<i>Price</i> in this example—simply aren’t added to the metadata, and thus 
no OData client on the other end of this whole scene will know about it let 
alone be able to retrieve values.</p>
<p>Also note that little call to <i>metadata.SetReadOnly()</i> within the <i>
DSPMetadata</i> class’ <i>Metadata</i> 
property. This effectively freezes the metadata so it cannot be modified within 
the scope of the current HTTP REQUEST that’s being processed—a good thing! It’s 
worth noting too that the WCF Data Services Framework will ask for metadata for 
each REQUEST, so you have the opportunity to reconstruct it as necessary on a 
per-request basis.</p>
<p>Things will get a little more complicated as you add support for inheritance, 
relationships, and service operations (filling in some of the stubbed-out 
methods above).</p>
<p>Finally, you might have noticed that there are two kinds of functions/properties 
on the <i>IDataServiceMetadataProvider</i> 
interface: those that return enumerations and those that try to find a specific 
instance. This is done for performance reasons. Most requests to the service use 
the <i>TryResolve*</i> methods, meaning that 
even if you have a lot of metadata you can often avoid creating most of it. 
Those methods that return the whole smash, on the other hand, are used much more 
sparingly, as when a data service is asked for all its metadata with a
<i>$metadata </i>in the URI.</p>



<h3>IDataServiceQueryProvider</h3>
<p>

The last piece that will complete a basic custom provider is an implementation 
of <i>IDataServiceQueryProvider</i>. This is 
already surfaced through the provider’s <i>
IServiceProvider.GetService</i> implementation, which returns an instance of the
<i>DSPResourceQueryProvider</i> class (it’s also created through the
<i>Metadata</i> property we just saw):</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
abstract</span> <span class="codeKeyword">class</span>
<span class="codeType">DSPDataService</span>&lt;T&gt; :
<span class="codeType">DataService</span>&lt;T&gt;, <span class="codeType">
IServiceProvider</span> <span class="codeKeyword">where</span> T :
<span class="codeType">DSPContext</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeType">DSPResourceQueryProvider</span> 
resourceQueryProvider;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">object</span> GetService(<span class="codeType">Type</span> 
serviceType)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (serviceType ==
<span class="codeKeyword">typeof</span>(<span class="codeType">IDataServiceMetadataProvider</span>))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this.</span>Metadata;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">else if</span> (serviceType ==
<span class="codeKeyword">typeof</span>(<span class="codeType">IDataServiceQueryProvider</span>))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this.</span>resourceQueryProvider;
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">else</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">null</span>;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>}</p>
</div>

<p><i>DSPResourceQueryProvider</i> is 
derived from <i>IDataServiceQueryProvider</i>, 
of course, implementing the six methods and two properties of that interface 
(DSPResourceQueryProvider.cs in the DataServiceProvider project; comments 
omitted for brevity):</p>

<div class="Code">
<p><span class="codeKeyword">internal</span>
<span class="codeKeyword">class</span> <span class="codeType">
DSPResourceQueryProvider</span> : <span class="codeType">
IDataServiceQueryProvider</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeType">DSPContext</span> dataSource;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeType">DSPMetadata</span> metadata;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">DSPResourceQueryProvider</span>(<span class="codeType">DSPMetadata</span> 
metadata)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>metadata = metadata;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">//IDataServiceQueryProvider Members</span></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">object</span>
<span class="codeType">CurrentDataSource</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">get</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this.</span>dataSource;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">set</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (<span class="codeKeyword">this.</span>dataSource 
!= <span class="codeKeyword">null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">InvalidOperationException</span>(<span class="codeString">&quot;CurrentDataSource 
should only be set once.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>dataSource = (<span class="codeType">DSPContext</span>)value;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">object</span> GetOpenPropertyValue(<span class="codeKeyword">object</span> 
target, <span class="codeKeyword">string</span> propertyName)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">NotSupportedException</span>(<span class="codeString">&quot;Open 
types are not yet supported.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">IEnumerable</span>&lt;<span class="codeType">KeyValuePair</span>&lt;<span class="codeKeyword">string</span>,
<span class="codeKeyword">object</span>&gt;&gt; GetOpenPropertyValues(<span class="codeKeyword">object</span> 
target)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">NotSupportedException</span>(<span class="codeString">&quot;Open 
types are not yet supported.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">object</span> GetPropertyValue(<span class="codeKeyword">object</span> 
target, <span class="codeType">ResourceProperty</span> resourceProperty)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> 
resourceProperty.GetAnnotation().InstanceProperty.GetValue(target,
<span class="codeKeyword">null</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeType">System.Linq.IQueryable</span> 
GetTypedQueryRootForResourceSet&lt;TElement&gt;(<span class="codeType">ResourceSet</span> 
resourceSet)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this.</span>dataSource.GetResourceSetEntities(resourceSet.Name).Cast&lt;<span class="codeType">TElement</span>&gt;().AsQueryable();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> System.Linq.IQueryable GetQueryRootForResourceSet(<span class="codeType">ResourceSet</span> 
resourceSet)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// We can&#39;t return the IList.AsQueryable directly as that would return in 
fact IQueryable&lt;object&gt;.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Currently WCF Data Services don&#39;t support that as it is required that 
the returned IQueryable&lt;T&gt; has T</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">//&nbsp;&nbsp;equal to the instance type of the base type of the resource set.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// So we need to Cast the returned collection first.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Use a helper method to do this for us.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">MethodInfo </span>getTypedQueryRootForResourceSetMethod = </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typeof(<span class="codeType">DSPResourceQueryProvider</span>).GetMethod(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;GetTypedQueryRootForResourceSet&quot;,
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">BindingFlags</span>.NonPublic | <span class="codeType">BindingFlags</span>.Instance);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> 
(<span class="codeType">IQueryable</span>)getTypedQueryRootForResourceSetMethod.MakeGenericMethod(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ResourceSet.ResourceType.InstanceType).Invoke(this,
<span class="codeKeyword">object</span>[] { resourceSet } );</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">ResourceType</span> 
GetResourceType(<span class="codeKeyword">object</span> target)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">Type</span> targetType = target.GetType();</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// (A rather slow/linear search of resource types)</span> </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this.</span>metadata.Types.Single(rt 
=&gt; rt.InstanceType == targetType);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">object</span> 
InvokeServiceOperation(<span class="codeType">ServiceOperation</span> 
serviceOperation, <span class="codeKeyword">object</span>[] parameters)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">NotSupportedException</span>(<span class="codeString">&quot;Service 
operations are not yet supported.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">bool</span> 
IsNullPropagationRequired</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">//This is so WCF Data Services can compensate for the lack of 
NullPropagation in LINQ to Objects</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">get</span> { <span class="codeKeyword">return</span>
<span class="codeKeyword">true</span>; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>}</p>
</div>

<p>As with <i>IDataServiceMetadataProvider</i>, 
most of these methods are one-line implementations. Indeed, if you only want to 
expose a service document and support <i>
$metadata</i> in the URI, you only need implement the
<i>CurrentDataSource</i> property; the rest 
of the methods are only called when data is actually queried. (In other words, replace all the 
other method code above with <i>throw new 
NotSupportedException(...)</i> and you can start there.)</p>

<p>Of course, most data sources will want to support queries as well, so let’s go into 
this whole mechanism a little more deeply.</p>
<p>The big job at hand is to translate the OData URI conventions that express query 
operations, such as <i>$filter</i>, into queries that the underlying data source actually understands. The WCF Data 
Services Framework, then, needs to describe that URI-based query to the 
underlying provider in some generalized language that is appropriate for both 
relational and non-relational data sources. For this, the framework has chosen 
to use LINQ expressions, especially because there are already many existing 
implementation of “query providers” that can handle LINQ expressions for a wide 
variety of data sources.</p>
<p>LINQ expressions are built up in an instance of the
<i>IQueryable </i>interface (from the System.Linq namespace), which holds 
in itself an expression tree to represent the query. (It then relies on an 
implementation of <i>IQueryProvider</i> to 
actually execute it). Thus for the WCF Data Services Framework to build a query 
from the information it’s parsing from the URI, it asks the data provider for an
<i>IQueryable</i>. This is the purpose of the 
main <i>IDataServiceQueryProvider</i> method 
in the code above, namely <i>
GetQueryRootForResourceSet</i>, returns an <i>
IQueryable</i>.</p>
<p>How your provider gets hold of an appropriate
<i>IQueryable </i>is, of course, an internal 
implementation detail. In the case of the Typed\RO sample, instances of
<i>IQueryable </i>can be easily obtained from 
the data source class, <i>DSPContext</i>. To be specific, <i>
GetQueryRootForResourceSet</i>, through some massaging to get the type set up 
properly, calling to the private helper <i>
GetTypedQueryRootForResourceSet. </i>This helper calls
<i>DSPContext.GetResourceSetEntities</i> 
which returns an appropriate <i>List</i> that 
can then be converted into an <i>IQueryable
</i>object using the <i>AsQueryable</i> 
method:</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
class</span> <span class="codeType">DSPContext</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeType">Dictionary</span>&lt;<span class="codeKeyword">string</span>,
<span class="codeType">List</span>&lt;<span class="codeKeyword">object</span>&gt;&gt; 
ResourceSetsStorage;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">DSPContext</span>()</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>ResourceSetsStorage =
<span class="codeKeyword">new</span> <span class="codeType">Dictionary</span>&lt;<span class="codeKeyword">string</span>,
<span class="codeType">List</span>&lt;<span class="codeKeyword">object</span>&gt;&gt;();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">IList</span> 
GetResourceSetEntities(<span class="codeKeyword">string</span> ResourceSetName)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">List</span>&lt;<span class="codeKeyword">object</span>&gt; 
entities;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!<span class="codeKeyword">this.</span><span class="codeType">ResourceSet</span>sStorage.TryGetValue(ResourceSetName,
<span class="codeKeyword">out</span> entities))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;entities = <span class="codeKeyword">new</span>
<span class="codeType">List</span>&lt;<span class="codeKeyword">object</span>&gt;();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>ResourceSetsStorage[ResourceSetName] 
= entities;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> entities;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>}</p>
</div>

<p>We get away with this in this sample because we have strongly-typed, in-memory data 
(as shown in <i>
DemoDSPDataService.CreateDataSource</i>) for which the .NET Framework can 
provide <i>IQueryable</i>. As we’ll see in 
Part 4, working with an untyped data source requires more work in this 
department, but for now we at least have a grasp of the basic mechanics and 
have, in hand, a fully functional query provider.</p>
<p>An important detail to point out is something you see in the implementation of the
<i>DSPMetadata</i> class (DSPMetadata.cs), 
specifically in its <i>AddEntityType, 
AddComplexType, AddProperty, </i>and<i> 
AddComplexProperty</i> methods. In these you’ll see flags called
<i>CanReflectOnInstance </i>set to
<i>true</i>, which is how the provider, 
through the metadata, tells the WCF Data Services Framework that it’s strongly 
typed. Because of this, the framework knows that it can get values directly from 
resource objects via reflection and so it will never actually call
<i>IDataServiceQueryProvider.GetPropertyValue</i>. 
Again, we’ll see that this changes in the untyped scenario.</p>


<h3>Query Interaction Psuedo-Code</h3>
<p>To review and deeper our understanding of how the framework interacts with the 
interfaces we’ve implemented thus far, the following pseudo-code shows the basic 
process for handling an HTTP GET request:</p>

<div class="Code">
<p><span class="codeComment">// Locate the service provider</span></p>
<p><span class="codeKeyword">var</span> dataservice = <span class="codeKeyword">
new</span> <span class="codeType">DataService</span>&lt;T&gt;;<br />
<span class="codeType">IServiceProvider</span> sp = 
dataservice <span class="codeKeyword">as</span> <span class="codeType">
IServiceProvider</span>;</p>
<p>&nbsp;</p>
<p><span class="codeKeyword">if</span> (sp ==
<span class="codeKeyword">null</span>) </p>
<p>{ </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Not really a data service 
with a custom provider</span></p>
<p>} </p>
<p>&nbsp;</p>
<p><span class="codeComment">// Get the various provider interfaces </span></p>
<p><span class="codeType">IDataServiceMetadataProvider</span> 
mdp = sp.GetService(typeof(<span class="codeType">IDataServiceMetadataProvider</span>));
</p>
<p><span class="codeType">IDataServiceQueryProvider</span> qp 
= sp.GetService(typeof(<span class="codeType">IDataServiceQueryProvider</span>));
</p>
<p>&nbsp;</p>
<p><span class="codeComment">// Set the CurrentDataSource (if necessary) </span></p>
<p><span class="codeKeyword">if</span> (qp.CurrentDataSource ==
<span class="codeKeyword">null</span>) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;qp.CurrentDataSource 
= dataservice.CreateDataService();
</p>
<p>&nbsp;</p>
<p><span class="codeComment">// Find the Products ResourceSet</span></p>
<p>var ResourceSet = <span class="codeKeyword">null</span>;</p>
<p>&nbsp;</p>
<p><span class="codeComment">// The &quot;Products&quot; text here would come from the URI, and 
not be hard-coded</span></p>
<p>if (!mdp.TryResolveResourceSet(&quot;Products&quot;,
<span class="codeKeyword">out</span> ResourceSet)) </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span>
<span class="codeKeyword">new</span> Exception(&quot;404&quot;);</p>
<p>&nbsp;</p>
<p><span class="codeComment">// Get the queryable for 
the ResourceSet </span></p>
<p><span class="codeType">IQueryable</span> queryRoot = 
qp.GetQueryRootForResourceSet(ResourceSet);</p>
<p>&nbsp;</p>
<p><span class="codeComment">// Compose expressions onto the 
IQueryable to represent $filter, $select etc. in the URI</span></p>
<p>queryRoot = Compose(options, queryRoot);</p>
<p>&nbsp;</p>
<p><span class="codeComment">// Start writing response </span></p>
<p>WriteStartODataFeed(); </p>
<p>&nbsp;</p>
<p><span class="codeComment">// Enumerate results </span></p>
<p><span class="codeKeyword">foreach</span> (<span class="codeKeyword">object</span> 
resource <span class="codeKeyword">in</span> queryRoot) </p>
<p>{ </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Get the ResourceType for resource. NOTE: because of inheritance it might be a 
resourceType </span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// derived from ResourceSet.ResourceType
</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> 
type = qp.GetResourceType(type); </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;WriteResource(resource,type);</p>
<p>} </p>
<p>&nbsp;</p>
<p>WriteEndODataFeed();</p>
</div>

<h3>Where We Are</h3>
<p>At this point we have a complete read-only data service. If you compile and run the 
project, it should start up an ASP.NET Development Server and show a browser 
like this, referencing DemoDSPDataService.svc in the URI:</p>
<p align="center">
<img src="assets/Figure2.png" alt="The default service document for the sample data service" /></p>
<p align="center">
Figure 2: The default service document for the sample data service.</p>
<p>&nbsp;</p>
<p>If you add <b>$metadata</b> to the URI you 
should see the following:</p>
<p align="center">
<img src="assets/Figure3.png" alt="The metadata returned for the sample data service." /></p>
<p align="center">Figure 3: The metadata returned for the sample data service.</p>
<p>&nbsp;</p>
<p>If you append <b>Products</b> instead, then 
you’ll see the individual items.</p>
<p align="center">
<img src="assets/Figure4.png" alt="The Products entity data returned by the sample data service." /></p>
<p align="center">Figure 4: The Products entity data 
returned by the sample data service.</p>
<p>&nbsp;</p>
<p>Filtering operations are also supported with the code we’ve seen thus far, if 
you’d like to give them a try. Adding <b>
?$filter=Name eq ‘Bread’ </b>to the URI (after Products in the preceding 
example), shows only those items in the Products collection that match.</p>
<p align="center">
<img src="assets/Figure5.png" alt="Data returned by a query to the sample data service." /></p>
<p align="center">Figure 5: Data returned by a query to the sample data service.</p>
<p>&nbsp;</p>


<h2>Part 2: Supporting Updates</h2>
<p>We’re now ready to start adding additional features to our 
basic read-only data service. We’ll start with adding update capabilities to 
create a read-write data service. This is mostly a matter of implementing
<i>IDataServiceUpdateProvider</i>, which is a derivative of <i>IUpdatable</i>. 
(This implies that if you already have an <em>IUpdatable </em>you need to expose 
it via <em>IDataServiceUpdateProvider </em>to make it work with the WCF Data 
Services Framework.)</p>
<p>The context for this section is the Typed\RW sample, which 
is the same as the Typed\RO solution with this added feature. The additions to 
Typed\RW are as follows:</p>
<ul>
	<li>DataServiceProvider project:<ul>
		<li>The implementation of
<em>IServiceProvider.GetService</em> now also checks for
<em>IDataServiceUpdateProvider</em> and returns 
an instance of the class <em>DSPUpdateProvider</em>.</li>
		<li>Contains a new file, DSPUpdateProvider.cs, that implements <em>DSPUpdateProvider</em>.</li>
		<li>The implementation of
<em>IDataServiceMetadataProvider</em> has a little added code.<br />
		<br />
		</li>
	</ul>
	</li>
	<li>DemoDSPDataService project:<ul>
		<li>The internal <em>CreateDataSource </em>method in DemoDSPDataService.svc.cs adds a session to the
<em>DSPContext </em>so changes are only applied to the current browser 
session. This is appropriate for an in-memory data source as we’re working with.</li>
		<li>The <em>InitializeService </em>method sets open read-write access rights where it formerly set read-only rights.</li>
	</ul>
	</li>
</ul>

<p>In this section we’ll be focusing only on the code in the 
DataServiceProvider project as the rest is rather self-explanatory.</p>
<p>It’s helpful to note here that the
<i>DSPContext</i> class, which manages our underlying data source, is 
inherently updatable: as a <i>Dictionary </i>
that contains <i>List </i>instances, any of 
it can be updated and modified at any time. Of course, other data sources may 
not be so straightforward, so it’s a worthwhile step to think through the 
implications of insert, update, and delete operations where your particular 
source is concerned. In other words, you may need to do a little work on those 
source classes before you can wire things together through
<i>IDataServiceUpdateProvider</i>.</p>

<h3>Implications of Batching</h3>
<p>Another consideration is that of batching. <i>
IDataServiceUpdateProvider</i> is inherently designed for this, meaning that a 
client can update many resources in a single request (that is, one HTTP PUT 
operation).</p>
<p>Updates happen through any number of calls to
<i>IDataServiceUpdateProvider.SetValue</i> 
(or other data-changing methods) followed by a call to
<i>IDataServiceUpdateProvider.SaveChanges</i>. When updating a single 
resource, there will be a <i>SetValue </i>
call for each changed property of the resource prior to
<i>SaveChanges.</i> Batching simply means 
that there may be <i>SetValue </i>calls for 
properties on multiple resources at once, all prior to
<i>SaveChanges</i>. But it also means that 
everything before that final call is considered an atomic transaction and must 
be rolled back if there is an error anywhere in the process.</p>
<p>The implication of all this is that you cannot just immediately apply every 
change as they come; you need to record those changes in a temporary place and only commit 
them as a group upon <i>SaveChanges</i>. They 
should also be recorded sequentially so that a resource can be created, for 
example, before values are set within it.</p>
<p>If your data resides in a database, this typically means recording a series 
of commands and issuing them as a group.</p>
<p>With an in-memory data source like we’re working with in the Typed\RW sample, 
however, we have to keep such a record ourselves. This is accomplished through a
<i>List&lt;Action&gt;</i> variable named <i>pendingChanges</i>, found in 
DSPUpdateProvider.cs. Every change made to our resources—through the
<i>CreateResource</i>, <i>DeleteResource</i>,
<i>ResetResource</i>, and <i>SetValue</i> methods—only adds an 
appropriate action to this list. <i>
SaveChanges </i>then iterates through the list and applies those changes. We’ll 
see the code shortly, and keep in mind that this is just an implementation 
detail that will vary between providers and data sources, as necessary.</p>

<h3>IDataServiceUpdateProvider</h3>
<p> As mentioned earlier, the <i>IDataServiceUpdateProvider</i> interface is derived from
<i>IUpdatable</i>; in fact,
<i>IDataServiceProvider</i> only adds a 
single method, <i>SetConcurrencyValues</i>, 
that isn’t even implemented in the Typed\RW sample. So what we’re really talking 
about here are the methods of <i>IUpdatable</i>. (For more details on <em>
SetConcurrencyValues</em>, see the <em>
<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataserviceupdateprovider(VS.100).aspx">
IDataServiceUpdateProvider</a></em> documentation.)</p>
<p>First, here’s the first part of the DSPUpdateProvider class 
(DSPUpdateProvider.cs) that implements the interface, so you can see the 
declaration of the <i>pendingChanges </i>
variable. The implementation of the <i>IUpdatable.ClearChanges</i> method is very simple as it just clears the
<i>pendingChanges</i> list;
<i>IUpdatable.SaveChanges</i>, as noted 
earlier, just goes through that list and applies the changes.</p>

<div class="Code">
<p><span class="codeKeyword">public</span>
<span class="codeKeyword">class</span> <span class="codeType">
DSPUpdateProvider</span> : <span class="codeType">
IDataServiceUpdateProvider</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeType">DSPContext</span> dataContext;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeType">DSPMetadata</span> 
metadata;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// List of pending changes to apply once 
SaveChanges is called.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> <span class="codeType">List</span>&lt;<span class="codeType">Action</span>&gt; 
pendingChanges;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> DSPUpdateProvider(<span class="codeType">DSPContext</span> 
dataContext, <span class="codeType">DSPMetadata</span> metadata)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>dataContext = dataContext;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>metadata = metadata;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>pendingChanges = <span class="codeKeyword">
new</span> <span class="codeType">List</span>&lt;<span class="codeType">Action</span>&gt;();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">void</span> 
ClearChanges()</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Simply clear the list of pending changes</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>pendingChanges.Clear();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">void</span> 
SaveChanges()</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Just run all the pending changes we gathered so far</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">foreach</span> (<span class="codeKeyword">var</span> 
pendingChange <span class="codeKeyword">in</span> <span class="codeKeyword">this.</span>pendingChanges)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pendingChange();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>pendingChanges.Clear();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>}</p>
</div>


<p>This leaves us to look at the interesting work that’s happening in the core 
methods of the interface as described in Table 2:</p>
<table class="style1" style="width: 100%">
	<tr>
		<td style="width: 203px"><strong>Method</strong></td>
		<td><strong>Purpose</strong></td>
	</tr>
	<tr>
		<td style="width: 203px"><em>CreateResource</em></td>
		<td>Creates new entity types on insert as well as new complex types on 
		insert and update requests (handling HTTP POST, PUT, and MERGE).</td>
	</tr>
	<tr>
		<td style="width: 203px"><em>DeleteResource</em></td>
		<td>Performs a deletion (handling HTTP DELETE).</td>
	</tr>
	<tr>
		<td style="width: 203px"><em>GetResource</em></td>
		<td>Retrieves a given resource.</td>
	</tr>
	<tr>
		<td style="width: 203px"><em>GetValue</em></td>
		<td>Retrieves the value of a property within a resource.</td>
	</tr>
	<tr>
		<td style="width: 203px"><em>ResetResource</em></td>
		<td>Resets the values in a resource to its default values.</td>
	</tr>
	<tr>
		<td style="width: 203px"><em>SetValue</em></td>
		<td>Changes the value of a property within a resource.</td>
	</tr>
</table>
<p align="center">Table 2: The core methods of the
<i>IDataServiceUpdateProvider</i> interface.</p>
<p>Just to note, the <i>AddReferenceToCollection</i>, <i>RemoveReferenceFromCollection,</i> and <i>SetReference</i> methods of
<i>IUpdatable</i> are not implemented in the Typed\RW sample, along <i>
IDataServiceUpdateProvider.SetConcurrencyValues</i>. These are used to support 
relationships and ETags, which we’ll discuss later. For now we can ignore these 
methods.</p>

<p>Also, <i>IUpdatable.RevolveResource</i> is a 
trivial implementation in this code. Generally speaking, the methods like
<i>CreateResource</i> return an abstract 
handle to a resource (type <i>object</i>);
<i>RevolveResource </i>then translates 
between a handle and the actual resource itself. This allows for a level of 
indirection wherein you might use proxies to maintain a change list (see the 
section on<i> GetResource </i>below). In this 
sample, though, we use the resources themselves as the handles so there’s no 
translation needed.</p>
<p>Let’s look now at each of the interesting methods in turn.</p>

<h4>CreateResource</h4>
<p><i>CreateResource</i> is 
invoked when an OData client sends an HTTP POST, PUT or MERGE request for 
various insertions and updates. As you can see in the 
code, <i>CreateResource </i>is only given the 
name of the resource set (<i>containerName</i> 
in the code below) in which the new resource will live, and the name of a type. 
What this means is that <i>CreateResource </i>
just creates a new resource with default values and adds it to the set (as will 
be processed by <i>SaveChanges</i>); if the 
WCF Data Services Framework has more specific values to place in this resource, 
it will follow up with calls to <i>SetValue</i>. 
For this reason it’s again imperative that your change-tracking implementation 
is sequential.</p>
<p>It is possible that <i>CreateResource </i>is 
called with <i>containerName</i> set to null. 
This means that a complex resource is being created and all we have to do is 
create an instance of the type and return it, in which case we don’t add any 
action to our list of pending changes.</p>
<p>In this implementation, you can see that we’re first making sure the type is valid 
by checking it against our metadata (which knows all that sort of stuff). We 
then create a resource of the type, and if <i>
containerName</i> is null we just return it. Otherwise we add an action to
<i>pendingChanges </i>that will add the new resource to its container.</p>

<div class="Code">
<p><span class="codeKeyword">public</span>
<span class="codeKeyword">object</span> CreateResource(<span class="codeKeyword">string</span> 
containerName, <span class="codeKeyword">string</span> fullTypeName)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> resourceType;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (!<span class="codeKeyword">this.</span>metadata.TryResolveResourceType(fullTypeName,
<span class="codeKeyword">out</span> resourceType))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;Unknown 
resource type &#39;&quot;</span> + fullTypeName + <span class="codeString">&quot;&#39;.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Create new instance of the underlying CLR type 
(this will set all properties to defaults)</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">object</span> newResource 
= <span class="codeType">Activator</span>.CreateInstance(resourceType.InstanceType);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (containerName != <span class="codeKeyword">
null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// We&#39;re creating an entity and should add it to the 
resource set</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// This check is just for documentation; this should 
never be called with non-entity type in this case.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (resourceType.ResourceTypeKind 
!= <span class="codeType">ResourceTypeKind</span>.EntityType)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;The 
specified resource type &#39;&quot;</span></p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>+ fullTypeName + <span class="codeString">&quot;&#39; is not an entity type, 
but resource set was specified.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">IList</span> 
resourceSetList = <span class="codeKeyword">this.</span>dataContext.GetResourceSetEntities(containerName);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// And register pending change to add the resource to 
the resource set list</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>pendingChanges.Add(() =&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resourceSetList.Add(<span class="codeKeyword">new</span>Resource);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">else</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// We&#39;re creating a complex type instance, so no 
additional operation is needed.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// This check is just for documentation; should never 
be called with non-complex type in this case.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (resourceType.ResourceTypeKind 
!= ResourceTypeKind.ComplexType)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;The 
specified resource type &#39;&quot;</span> </p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>+ fullTypeName + <span class="codeString">&quot;&#39; is not a complex type.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p><span class="codeComment">
&nbsp;&nbsp;&nbsp; // The method should 
return the resource &quot;handle&quot;, we don&#39;t have handles so return the resource 
directly.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> newResource;</p>
<p>}</p>
</div>


<p>Note the last comment above. The different methods in this interface are 
designed to work with handles or proxies that represent the resource (in the 
code here we&#39;re simply using the resource itself as that handle). This allows 
for an extra layer of indirection so that an intermediate proxy could maintain, 
for example, a copy of the data being manipulated (like an ADO.NET DataSet).</p>

<h4>DeleteResource</h4>
<p><i>DeleteResource</i> is 
given the handle to the resource to delete, which in our implementation is the 
resource itself. In response, we first determine which set the resource belongs 
to, then add an action to <i>pendingChanges
</i>to affect the removal when <i>SaveChanges</i> 
is called.</p>

<div class="Code">
<p><span class="codeKeyword">public</span>
<span class="codeKeyword">void</span> DeleteResource(<span class="codeKeyword">object</span> targetResource)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Get the resource type of the resource specified so that we know which 
resource set it belongs to</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">Type</span> instanceType = targetResource.GetType();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> resourceType;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (!<span class="codeKeyword">this.</span>metadata.TryResolveResourceType(instanceType,
<span class="codeKeyword">out</span> resourceType))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;Unknown 
resource type for instance type &#39;&quot;</span></p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>+ instanceType.ToString() +
<span class="codeString">&quot;&#39;.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceSet</span> ResourceSet 
= resourceType.GetAnnotation().ResourceSet;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">IList</span> resourceSetList 
= <span class="codeKeyword">this.</span>dataContext.GetResourceSetEntities(ResourceSet.Name);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Add a pending change to remove the resource from 
the resource set</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>pendingChanges.Add(() =&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resourceSetList.Remove(targetResource);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</p>
<p>}</p>
</div>


<h4>GetResource</h4>
<p>When the WCF Data Services Framework tries to update or delete a resource, it 
first needs to retrieve that resource or a representation of it. This is where
<i>GetResource</i> comes into play.</p>
<p>The method is interesting in that it’s given a query (<i>IQueryable</i>) to identify the resource. This query should only 
identify a single resource; it should fail if zero or multiple results come out 
of the query, which is the purpose of the <i>
foreach </i>statement in this code. Beyond that, we check to make sure the types 
are valid, then return the resource if all is well.</p>
<p>Note again that this method is specified to return a handle, allowing for a 
level of indirection so you can employ proxies or whatnot. (Such 
implementations, though, would avoid the use of <em>Actions </em>as we&#39;re using 
in this code.) </p>

<div class="Code">
<p><span class="codeKeyword">public</span>
<span class="codeKeyword">object</span> GetResource(<span class="codeType">System.Linq.IQueryable</span> 
query, <span class="codeKeyword">string</span> fullTypeName)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Since we&#39;re not using resource handles we&#39;re going to return the resource 
itself.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">object</span> resource = <span class="codeKeyword">null</span>;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">foreach</span> (<span class="codeKeyword">object</span> 
r <span class="codeKeyword">in</span> query)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (resource != <span class="codeKeyword">null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(</p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>String.Format(<span class="codeString">&quot;Invalid 
Uri specified. The query &#39;{0}&#39; must refer to a single resource&quot;</span>,</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;query.ToString()));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource = r;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (resource != <span class="codeKeyword">null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (fullTypeName != <span class="codeKeyword">
null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> resourceType;</p>
<p>&nbsp;</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (!<span class="codeKeyword">this.</span>metadata.TryResolveResourceType(fullTypeName,
<span class="codeKeyword">out</span> resourceType))</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;Unknown 
resource type &#39;&quot;</span> + fullTypeName + <span class="codeString">&quot;&#39;.&quot;</span>);</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> 
(resource.GetType() != 
resourceType.InstanceType)</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span> 
System.<span class="codeType">ArgumentException</span>(</p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>String.Format(<span class="codeString">&quot;Invalid 
uri specified. ExpectedType: &#39;{0}&#39;, ActualType: &#39;{1}&#39;&quot;</span>,</p>
<p><span class="codeType">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
&nbsp;fullTypeName, resource.GetType().FullName));</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> resource;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">null</span>;</p>
<p>}</p>
</div>

<h4>GetValue</h4>
<p><i>GetValue</i> is a simple method to retrieve a named property from a given resource (the
<i>targetResource </i>is specified as a 
handle, so you’ll always want to do the appropriate conversion). As with
<i>GetResource, </i>this method exists to provide a level of indirection, giving 
you more control over how you implement your change list.</p>

<div class="Code">
<p><span class="codeKeyword">public</span>
<span class="codeKeyword">object</span> GetValue(<span class="codeKeyword">object</span> targetResource,
<span class="codeKeyword">string</span> propertyName)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Note that since our resource property name does not necessarily have to match 
the name of</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// the instance CLR property we need to find the resource property specified by 
the</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// propertyName and use its instance property to access the CLR property on the 
resource.</span></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Get the resource type of the resource specified</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">Type</span> instanceType = targetResource.GetType();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> resourceType;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (!<span class="codeKeyword">this.</span>metadata.TryResolve<span class="codeType">ResourceType</span>(instanceType,
<span class="codeKeyword">out</span> resourceType))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;Unknown 
resource type for instance type &#39;&quot;</span></p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>+ instanceType.ToString() +
<span class="codeString">&quot;&#39;.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Find the property of the specified name on it</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceProperty</span> resourceProperty = 
resourceType.Properties.FirstOrDefault(rp =&gt; rp.Name == propertyName);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (resourceProperty == <span class="codeKeyword">
null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;Unknown 
resource property &#39;&quot;</span></p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>+ propertyName + <span class="codeString">&quot;&#39; on resource type &#39;&quot;</span> 
+ resourceType.FullName + <span class="codeString">&quot;&#39;.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Simply use reflection to get the value of the property</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> resourceProperty.GetAnnotation().InstanceProperty.GetValue(targetResource, <span class="codeKeyword">null</span>);</p>
<p>}</p>
</div>


<h4>ResetResource</h4>
<p>Just as <i>CreateResource </i>creates a new resource with default values,
<i>ResetResource </i>reverts all values in a resource to those same 
defaults. It&#39;s used to handle PUT requests to an entity.</p>
<p><i>ResetResource </i>can 
do this either by modifying the existing resource or by simply creating a new 
one and returning a handle to it. In the latter case, this method must also 
replace the old resource with the new one in its resource set and patch up any 
references to the old.</p>
<p>Note also that returned resource must have the same 
identity as the one on the input, meaning that its “key” properties must all 
have the same values. </p>
<p>As with updating other values, resetting a resource means 
adding an action to the pending change list. </p>

<div class="Code">
<p><span class="codeKeyword">public</span>
<span class="codeKeyword">object</span> ResetResource(<span class="codeKeyword">object</span> 
resource)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Get the resource type of the resource specified</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">Type</span> instanceType = resource.GetType();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> resourceType;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (!<span class="codeKeyword">this.</span>metadata.TryResolveResourceType(instanceType,
<span class="codeKeyword">out</span> resourceType))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;Unknown 
resource type for instance type &#39;&quot;</span></p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>+ instanceType.ToString() +
<span class="codeString">&quot;&#39;.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// We are going to create a new resource and then set all the properties on the 
existing </span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// resource to the values of those properties on the newly created resource. 
This is to</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// allow constructors for the resources to specify default values for the 
properties.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// We are not going return a different resource instance, so no need to replace 
the resource or such.</span></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">object</span> newResource 
= <span class="codeType">Activator</span>.CreateInstance(resourceType.InstanceType);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>pendingChanges.Add(() =&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">foreach</span> (<span class="codeKeyword">var</span> 
resourceProperty <span class="codeKeyword">in</span> resourceType.Properties)</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// We will only copy non-key properties as we 
have to preserve the value of the key properties.</span></p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> ((resourceProperty.Kind &amp; 
ResourcePropertyKind.Key) != ResourcePropertyKind.Key)</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">object</span> propertyValue = resourceProperty.GetAnnotation()</p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>.InstanceProperty.GetValue(newResource, <span class="codeKeyword">null</span>);</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resourceProperty.GetAnnotation().InstanceProperty.SetValue(resource, 
propertyValue, <span class="codeKeyword">null</span>);</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> resource;</p>
<p>}</p>
</div>

<h4>SetValue</h4>
<p>Finally, <i>SetValue </i>sets the value of a named 
property within a given resource (whose handle is in
<i>targetResource</i>). This is, as you would expect, the workhorse method 
for most updates, and you can expect that updating a resource will generate 
multiple calls here. Each change, of course, is added to the pending change 
list.</p>

<div class="Code">
<p><span class="codeKeyword">public</span>
<span class="codeKeyword">void</span> SetValue(<span class="codeKeyword">object</span> targetResource,
<span class="codeKeyword">string</span> propertyName, <span class="codeKeyword">
object</span> propertyValue)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Note that since our resource property name does not necessarily have to match 
the name of</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// the instance CLR property we need to find the resource property specified by 
the propertyName</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// and use its instance property to access the CLR property on the resource.</span></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Get the resource type of the resource specified</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">Type</span> instanceType = targetResource.GetType();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> resourceType;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (!<span class="codeKeyword">this.</span>metadata.TryResolve<span class="codeType">ResourceType</span>(instanceType,
<span class="codeKeyword">out</span> resourceType))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;Unknown 
resource type for instance type &#39;&quot;</span></p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>+ instanceType.ToString() +
<span class="codeString">&quot;&#39;.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Find the property of the specified name on it</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceProperty</span> resourceProperty = 
resourceType.Properties.FirstOrDefault(rp =&gt; rp.Name == propertyName);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (resourceProperty == <span class="codeKeyword">
null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;Unknown 
resource property &#39;&quot;</span> + propertyName</p>
<p><span class="codeKeyword">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>+ <span class="codeString">&quot;&#39; on resource type &#39;&quot;</span> + 
resourceType.FullName + <span class="codeString">&quot;&#39;.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Add a pending change to modify the value of the 
property</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this.</span>pendingChanges.Add(() =&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resourceProperty.</span>GetAnnotation().InstanceProperty.SetValue(</span>targetResource, 
propertyValue, <span class="codeKeyword">null</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</p>
<p>}</p>
</div>


<h3>Give It a Try</h3>
<p>With insert, update, and delete support now working, you 
can give the data service another go through a client program that can send the 
appropriate HTTP request. You can’t do this directly in the browser, however, 
because typing a URI in the address bar will only generate HTTP GET requests.</p>
<p>You can, however, follow some of the code in the DSPTest project. As noted 
before, this project contains test code that is invoked through Visual Studio&#39;s 
Test | Run | All Tests in Solution menu command. In the Typed\RW solution, you&#39;ll 
see that this project has an UpdateTests.cs code file that calls methods on a
<em>DataServiceContext</em> object to do insertions, updates, and deletes 
against the data service. These calls, of course, generate the necessary HTTP 
requests.</p>
<p>&nbsp;</p>

<h2>Part 3: Supporting Relationships</h2>
<p>To this point we’ve implemented a read-write typed 
provider, but it’s still a little simplistic because it doesn’t support 
relationships (or “navigation properties” in Entity Framework parlance).</p>
<p>To demonstrate this, we’ll be adding another entity type to 
our sample, specifically a class called <i>
CatalogEntity</i>. The code for this variation can be found in the 
Typed\RWNavProp sample. Compared with the Typed\RW sample, the changes are as 
follows:</p>
<ul>
	<li>DemoDSPDataService project:<ul>
		<li>Adds a new <em>CategoryEntity</em> class and a relationship between a product and a category.</li>
		<li>Describes the new entity in the metadata.<br />
		</li>
	</ul>
	</li>
	<li>DataServiceProvider project:<ul>
		<li>In the <em>DSPMetadata </em>class that implements <em>IDataServiceMetadataProvider</em>, we now implement the
		<em>GetResourceAssociationSet </em>method of 
the interface.</li>
		<li>In the <em>DSPUpdateProvider</em> class that implements
<em>IDataServiceUpdateProvider</em>, we now 
implement the <em>AddReferenceToCollection</em>,
<em>RemoveReferenceFromCollection</em>, and
<em>SetReference</em> methods.</li>
	</ul>
	</li>
</ul>

<h3>Added Code in DemoDSPDataService.svc.cs</h3>
<p>Before getting into the details of the provider, here are 
the bits of code at the service level that add this new entity type and its 
associated metadata. All of this is found in DemoDSPDataService.svc.cs.</p>
<p>First, the <i>
CategoryEntity</i> class and an added <i>
Category </i>field within <i>ProductEntity</i>:</p>
<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
class</span> <span class="codeType">ProductEntity</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">CategoryEntity</span> Category {
<span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; }</p>
<p>}</p>
<p>&nbsp;</p>
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
class</span> <span class="codeType">CategoryEntity</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> CategoryEntity()</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this</span>.Products = <span class="codeKeyword">
new</span> <span class="codeType">List</span>&lt;<span class="codeType">ProductEntity</span>&gt;();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">int</span> ID {
<span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">string</span> Name {
<span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeType">List</span>&lt;<span class="codeType">ProductEntity</span>&gt; 
Products { <span class="codeKeyword">get</span>; <span class="codeKeyword">set</span>; 
}</p>
<p>}</p>
</div>

<p>The <i>CreateDataSource</i> method also 
creates a little initial category data for this class as well as the
<i>Category</i> field within
<i>ProductEntity</i>. Note that the 
implementation of <i>
DSPContext.GetResourceSetEntities</i> creates the Categories list if it doesn’t 
exist; no changes to <i>DSPContext</i> (the 
data source) are necessary for supporting these associations. In fact, because 
the query provider code (DSPResourceQueryProvider.cs) just works with the names of resource sets generally,
<i>Categories</i> becomes 
automatically available to queries as well.</p>
<div class="Code">
<p><span class="codeType">IList</span> categories = 
context.GetResourceSetEntities(<span class="codeString">&quot;Categories&quot;</span>);</p>
<p>&nbsp;</p>
<p><span class="codeType">CategoryEntity</span> food =
<span class="codeKeyword">new</span> <span class="codeType">CategoryEntity</span>();</p>
<p>food.ID = 0;</p>
<p>food.Name = <span class="codeString">&quot;Food&quot;</span>;</p>
<p>categories.Add(food);</p>
<p>&nbsp;</p>
<p><span class="codeType">CategoryEntity</span> beverages =
<span class="codeKeyword">new</span> <span class="codeType">CategoryEntity</span>();</p>
<p>beverages.ID = 1;</p>
<p>beverages.Name = <span class="codeString">&quot;Beverages&quot;</span>;</p>
<p>categories.Add(beverages);</p>
<p>&nbsp;</p>
<p>bread.Category = food;</p>
<p>food.Products.Add(bread);</p>
<p>milk.Category = beverages;</p>
<p>beverages.Products.Add(milk);</p>
<p>wine.Category = beverages;</p>
<p>beverages.Products.Add(wine);</p>
<p>&nbsp;</p>
</div>

<p>We do, of course, need to describe this new type (and the relationship between 
products and categories) in the metadata created within
<i>CreateDSPMetadata</i>:</p>
<div class="Code">
<p><span class="codeKeyword">protected</span>
<span class="codeKeyword">override</span> <span class="codeType">DSPMetadata</span> 
CreateDSPMetadata()</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">//Same code to create metadata for Products as before</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> category = metadata.AddEntityType(<span class="codeKeyword">typeof</span>(<span class="codeType">CategoryEntity</span>),
<span class="codeString">&quot;Category&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddKeyProperty(category, <span class="codeString">&quot;ID&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(category, <span class="codeString">&quot;Name&quot;</span>);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceSet</span> categories = metadata.AddResourceSet(<span class="codeString">&quot;Categories&quot;</span>, 
category);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Add reference properties between category and product</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddResourceReferenceProperty(product, <span class="codeString">
&quot;Category&quot;</span>, categories);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddResourceSetReferenceProperty(category, <span class="codeString">
&quot;Products&quot;</span>, products);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> metadata;</p>
<p>}</p>
</div>

<p>Note that both <i>ResourceType</i> instances 
of the related entities need to be at least partially created before you can 
create and add the navigation properties to them. Also note
<i>ProductEntity.Category </i>is a resource 
reference because there is just one category for a product. On the other hand,
<i>CategoryEntity.Products </i>is a resource 
set reference because it’s a collection.</p>
<p>Now if you follow the code here down into DSPMetadata.cs, you’ll see that the
<i>AddResourceReferenceProperty</i> and
<i>AddResourceSetReferenceProperty</i> helper 
functions call into an internal helper function
<i>AddReferenceProperty</i>. (Just to be clear, these are implementation 
helpers in the sample and not part of any API.) Eventually in that helper you’ll 
find the creation of the <i>
ResourceAssociationSet</i> class, which is provided by the WCF Data Services 
Framework. This is the object that tells the framework that there&#39;s a 
relationship between two resource sets and which properties contain the links.</p>
<h3>Changes in IDataServiceMetadataProvider</h3>
<p>As noted earlier, we need to round out the metadata 
provider implementation to support relationships. This is done through the<i> 
GetAssociationSet </i>method:</p>

<div class="Code">
<p><span class="codeKeyword">public</span>
<span class="codeType">ResourceAssociationSet</span> 
GetResourceAssociationSet(<span class="codeType">ResourceSet</span> 
resourceSet, <span class="codeType">ResourceType</span> resourceType,</p>
<p><span class="codeKeyword">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="codeType">ResourceProperty</span> 
resourceProperty)</p>
<p>{</p>
<p><span class="codeComment">&nbsp;&nbsp;&nbsp;&nbsp;// We have the resource association set precreated on the property 
annotation,</span></p>
<p><span class="codeComment">&nbsp;&nbsp;&nbsp;&nbsp;//so no need to compute anything in here</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceAssociationSet</span> resourceAssociationSet = 
resourceProperty.GetAnnotation().ResourceAssociationSet;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> resourceAssociationSet;</p>
<p>}</p>
</div>


<p>As the code comments suggest, much of the work has already been done before this 
method is ever called, namely in the aforementioned helper functions
<i>AddResourceReferenceProperty</i> and
<i>AddResourceSetReferenceProperty</i> that 
are invoked when the metadata is created. (These are new to the Typed\RWNavProp 
sample; some long strings have been omitted from this listing.)</p>

<div class="Code">
<p><span class="codeComment">// Adds a resource reference property to the specified ResourceType</span></p>
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
void</span> AddResourceReferenceProperty(<span class="codeType">ResourceType</span> 
resourceType, <span class="codeKeyword">string</span> name,
<span class="codeType">ResourceSet</span> targetResourceSet)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;AddReferenceProperty(resourceType, name, targetResourceSet,
<span class="codeKeyword">false</span>);</p>
<p>}</p>
<p>&nbsp;</p>
<p><span class="codeComment">// Adds a resource set reference property to the specified ResourceType</span></p>
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
void</span> AddResourceSetReferenceProperty(<span class="codeType">ResourceType</span> 
resourceType, <span class="codeKeyword">string</span> name,
<span class="codeType">ResourceSet</span> targetResourceSet)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;AddReferenceProperty(resourceType, name, targetResourceSet,
<span class="codeKeyword">true</span>);</p>
<p>}</p>
<p>&nbsp;</p>
<p><span class="codeKeyword">private</span> <span class="codeKeyword">
void</span> AddReferenceProperty(<span class="codeType">ResourceType</span> 
resourceType, <span class="codeKeyword">string</span> name,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceSet</span> targetResourceSet,
<span class="codeKeyword">bool</span> resourceSetReference)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">PropertyInfo</span> propertyInfo = 
resourceType.InstanceType.GetProperty(name, <span class="codeType">
BindingFlags</span>.Public | </p>
<p><span class="codeType">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BindingFlags</span>.Instance);</p>
<p>&nbsp;</p>
<p><span class="codeKeyword">&nbsp;&nbsp;&nbsp;&nbsp;if</span> (propertyInfo == <span class="codeKeyword">null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;Can&#39;t 
add a property which does not exist on the instance type.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (resourceSetReference)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (!<span class="codeKeyword">typeof</span>(<span class="codeType">IList</span>).IsAssignableFrom(propertyInfo.PropertyType))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">...</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">Type</span> enumerableOfT =
<span class="codeKeyword">typeof</span>(<span class="codeType">IEnumerable</span>&lt;&gt;).MakeGenericType(targetResourceSet.ResourceType.InstanceType);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> 
(!enumerableOfT.IsAssignableFrom(propertyInfo.PropertyType))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">...</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">else</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (propertyInfo.PropertyType != 
targetResourceSet.ResourceType.InstanceType)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">...</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceProperty</span> property = <span class="codeKeyword">new</span>
<span class="codeType">ResourceProperty</span>(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name, </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resourceSetReference ? <span class="codeType">ResourcePropertyKind</span>.ResourceSetReference 
: </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourcePropertyKind</span>.ResourceReference, 
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;targetResourceSet.ResourceType);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;property.CanReflectOnInstanceTypeProperty = <span class="codeKeyword">true</span>;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;resourceType.AddProperty(property);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// We don&#39;t support type inheritance so the property can only point to the base 
resource type</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// of the target resource set. We also don&#39;t support MEST, that is having two 
resource sets with</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// the same resource type, so we can determine the resource set from the 
resource type. That also</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// means that the property can never point to different resource sets so we can 
precreate the
</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// ResourceAssociationSet for this property right here as we have all the 
information.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;property.CustomState = <span class="codeKeyword">new</span>
<span class="codeType">ResourcePropertyAnnotation</span>()</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InstanceProperty = propertyInfo,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ResourceAssociationSet = <span class="codeKeyword">new</span>
<span class="codeType">ResourceAssociationSet</span>(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resourceType.Name + <span class="codeString">&quot;_&quot;</span> + name +
<span class="codeString">&quot;_&quot;</span> + targetResourceSet.Name,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">new</span> <span class="codeType">
ResourceAssociationSetEnd</span>(resourceType.GetAnnotation().ResourceSet, 
resourceType, property),</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">new</span> <span class="codeType">
ResourceAssociationSetEnd</span>(targetResourceSet, 
targetResourceSet.ResourceType, <span class="codeKeyword">null</span>))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;};</p>
<p>}</p>
</div>



<p>With these associations you can now traverse the relationships in the data 
service URIs, and query across both. For example, you can use a URI like
<i>DemoDSPDataService.svc/Products(0)/Category</i> and see the category of a 
particular product:</p>

<p align="center">
<img src="assets/Figure6.png" alt="Following a Products-to-Category association in the sample data service."/></p>
<p align="center">Figure 6: Following a 
Products-to-Category association in the sample data service.</p>
<p>&nbsp;</p>
<p>Similarly, a URI with <i>
Categories(1)/Products</i> will return the products in a given category (in this 
case the “Beverages” category):</p>
<p align="center">
<img src="assets/Figure7.png" alt="Following a Category-to-Products association in the sample data service."/></p>
<p align="center">
Figure 7: Following a 
Category-to-Products association in the sample data service.</p>
<p>&nbsp;</p>

<h3>Changes in IDataServiceUpdateProvider</h3>
<p>Because we now support references, we need to update the
<i>DSPUpdateProvider</i> class to implement 
the <i>AddReferenceToCollection</i>,
<i>RemoveReferenceFromCollection, </i>and
<i>SetReference </i>methods of
<i>IDataServiceUpdateProvider</i>. As with 
other update operations, any changes made through these methods also go into the 
pending changelist (the <em>pendingChanges </em>variable) to be processed when <i>
SaveChanges </i>is called.</p>

<h4>AddReferenceToCollection</h4>
<p>This method is given the handle to the target resource, the 
name of the reference (navigation) property, and the handle of the resource to 
add in that property. The short of it here is a simple matter of adding that 
resource to the collection in the target:</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
void</span> AddReferenceToCollection(<span class="codeKeyword">object</span> 
targetResource, <span class="codeKeyword">string</span> propertyName,
<span class="codeKeyword">object</span> resourceToBeAdded)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// In our case we make sure that all resource set reference properties 
are backed by a CLR</span></p>
<p><span class="codeComment">&nbsp;&nbsp;&nbsp;&nbsp;// property of type which implements IList so we get the value of the 
property, cast it to IList</span></p>
<p><span class="codeComment">&nbsp;&nbsp;&nbsp;&nbsp;// and add the new resource to the list using that interface. We don&#39;t 
use resource &quot;handles&quot; so</span></p>
<p><span class="codeComment">&nbsp;&nbsp;&nbsp;&nbsp;// both resources passed in as parameters are the real resource 
instances.</span></p>
<p><span class="codeComment">&nbsp;&nbsp;&nbsp;&nbsp;//</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Note that we don&#39;t support bi-directional relationships so we only 
handle the one</span></p>
<p><span class="codeComment">&nbsp;&nbsp;&nbsp;&nbsp;// resource set reference property in isolation.</span></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// We will use the GetValue we already implement to get the IList</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">IList</span> list = <span class="codeKeyword">this</span>.GetValue(targetResource, 
propertyName) <span class="codeKeyword">as</span> <span class="codeType">
IList</span>;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (list == <span class="codeKeyword">null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;The 
value of the property &#39;&quot;</span> + propertyName</p>
<p><span class="codeKeyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>+ <span class="codeString">&quot;&#39; does not implement IList, which 
is a requirement for resource set reference property.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this</span>.pendingChanges.Add(() =&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Add(resourceToBeAdded);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</p>
<p>}</p>
</div>

<h4>RemoveReferenceFromCollection</h4>
<p>This method is similarly straightforward, just the inverse 
of the <i>Add</i> method above:</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
void</span> RemoveReferenceFromCollection(<span class="codeKeyword">object</span> 
targetResource, <span class="codeKeyword">string</span> propertyName,
<span class="codeKeyword">object</span> resourceToBeRemoved)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">IList</span> list = <span class="codeKeyword">this</span>.GetValue(targetResource, 
propertyName) <span class="codeKeyword">as</span> <span class="codeType">
IList</span>;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (list == <span class="codeKeyword">null</span>)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;The 
value of the property &#39;&quot;</span> + propertyName</p>
<p><span class="codeKeyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>+ <span class="codeString">&quot;&#39; does not implement IList, which 
is a requirement for resource set reference property.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this</span>.pendingChanges.Add(() =&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Remove(resourceToBeRemoved);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</p>
<p>}</p>
</div>

<h4>SetReference</h4>
<p>Finally, <i>SetReference
</i>is just a one-line implementation:</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
void</span> SetReference(<span class="codeKeyword">object</span> targetResource,
<span class="codeKeyword">string</span> propertyName, <span class="codeKeyword">
object</span> propertyValue)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Our reference properties are just like normal properties we just set 
the property value to the new value</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// we don&#39;t perform any special actions for references. So just call the 
SetValue which will do exactly that.</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this</span>.SetValue(targetResource, propertyName, propertyValue);</p>
<p>}</p>
</div>

<p>And with that, we’ve completed a strongly-typed read-write 
data service with relationship support!</p>



<h2>Part 4: Basic Read-Only Untyped Data Provider</h2>
<p>We’ll now explore the details of the different untyped provider samples. Each 
of these solutions contains the same basic structure as the typed samples we’ve 
been working with: a service project (ODataDemo), a provider project 
(DataServiceProvider), and a test project (DSPTest). We’ll be starting in this 
section with the UnTyped\RO sample, followed by UnTyped\RW (Part 
5).</p>
<p>As you probably expect, the UnTyped\RO sample is similar to 
the Typed\RO as they implement the same feature set and, in fact, provide the 
same data. The big differences are in the underlying classes that compose the 
data source. Whereas Typed\RO uses specific CLR classes (like
<i>ProductEntity</i>), UnTyped\RO simply uses 
generic classes like <em>Dictionary</em>.</p>
<p>This is clearly seen in the ODataDemo project’s 
DemoDSPDataService.svc.cs code, specifically within the
<i>DemoDSPDataService.CreateDataSource</i> and
<i>DemoDSPDataService.CreateMetadata</i> methods. In the former, the data 
source is initialized using a generalized <i>
DSPResource</i> type that’s basically a wrapper for a
<i>Dictionary </i>containing a bag of properties (see the DataServiceProvider 
project, DSPResource.cs). Note also that in the UnTyped\RO sample, the data source starts off with both
<i>Products</i> and
<i>Categories</i> and relationships between 
them, something that wasn’t added in the typed samples until later (see Part 3 
above).</p>
<div class="Code">
<p><span class="codeKeyword">protected</span>
<span class="codeKeyword">override</span> <span class="codeType">DSPMetadata</span> 
CreateDSPMetadata()</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">DSPMetadata</span> metadata = <span class="codeKeyword">new</span>
<span class="codeType">DSPMetadata</span>(<span class="codeString">&quot;DemoService&quot;</span>,
<span class="codeString">&quot;DataServiceProviderDemo&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> product = metadata.AddEntityType(<span class="codeString">&quot;Product&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddKeyProperty(product, <span class="codeString">&quot;ID&quot;</span>,
<span class="codeKeyword">typeof</span>(<span class="codeKeyword">int</span>));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(product, <span class="codeString">&quot;Name&quot;</span>,
<span class="codeKeyword">typeof</span>(<span class="codeKeyword">string</span>));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(product, <span class="codeString">&quot;Description&quot;</span>,
<span class="codeKeyword">typeof</span>(<span class="codeKeyword">string</span>));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(product, <span class="codeString">&quot;ReleaseDate&quot;</span>,
<span class="codeKeyword">typeof</span>(<span class="codeType">DateTime</span>));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(product, <span class="codeString">
&quot;DiscontinueDate&quot;</span>, <span class="codeKeyword">typeof</span>(<span class="codeType">DateTime</span>?));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(product, <span class="codeString">&quot;Rating&quot;</span>,
<span class="codeKeyword">typeof</span>(<span class="codeKeyword">int</span>));</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceSet</span> products = metadata.AddResourceSet(<span class="codeString">&quot;Products&quot;</span>, 
product);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> category = metadata.AddEntityType(<span class="codeString">&quot;Category&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddKeyProperty(category, <span class="codeString">&quot;ID&quot;</span>,
<span class="codeKeyword">typeof</span>(<span class="codeKeyword">int</span>));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddPrimitiveProperty(category, <span class="codeString">&quot;Name&quot;</span>,
<span class="codeKeyword">typeof</span>(<span class="codeKeyword">string</span>));</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceSet</span> categories = metadata.AddResourceSet(<span class="codeString">&quot;Categories&quot;</span>, 
category);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Add reference properties between category and product</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddResourceReferenceProperty(product, <span class="codeString">
&quot;Category&quot;</span>, categories);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;metadata.AddResourceSetReferenceProperty(category, <span class="codeString">
&quot;Products&quot;</span>, products);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> metadata;</p>
<p>}</p>
</div>

<p>If you compare this code to the typed version in Part 1, you’ll see that here we’re 
explicitly declaring types for every property of the entity types. This wasn’t 
necessary before with a strongly-typed provider because everything could be 
determined using reflection.</p>
<p>As a result, the metadata helper class, <i>
DSPMetadata </i>(found in DataServiceProvider/DSPMetadata.cs) as it exists in 
UnTyped\RO now maintains explicit type information for every entity and every 
property of those entities. (Similarly, the
<i>DSPContext </i>class in 
DataServiceProvider/DSPContext.cs also maintains explicit type information 
through a class called <i>DSPResource</i>.)</p>
<p>There is one other key difference in the
<i>DSPMetadata</i> class implementation, specifically in that 
properties like <i>
ResourceType.CanReflectOnInstanceType</i> and
<i>
ResourceProperty.CanReflectOnInstanceTypeProperty </i>are all set to
<i>false</i>:</p>


<div class="Code">
<p><span class="codeKeyword">public</span>
<span class="codeType">ResourceType</span> AddEntityType(<span class="codeKeyword">string</span> 
name)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> resourceType = <span class="codeKeyword">new</span>
<span class="codeType">ResourceType</span>(<span class="codeKeyword">typeof</span>(<span class="codeType">DSPResource</span>),
<span class="codeType">ResourceTypeKind</span>.EntityType,</p>
<p><span class="codeType">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="codeKeyword">null</span>, <span class="codeKeyword">
this</span>.namespaceName, name, <span class="codeKeyword">false</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;resourceType.CanReflectOnInstanceType = <span class="codeKeyword">false</span>;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;resourceType.CustomState = <span class="codeKeyword">new</span>
<span class="codeType">ResourceTypeAnnotation</span>();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this</span>.resourceTypes.Add(resourceType.FullName, resourceType);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> resourceType;</p>
<p>}</p>
<p>&nbsp;</p>
<p><span class="codeKeyword">public</span>
<span class="codeType">ResourceType</span> AddComplexType(<span class="codeKeyword">string</span> 
name)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> resourceType =
<span class="codeKeyword">new</span> <span class="codeType">ResourceType</span>(<span class="codeKeyword">typeof</span>(<span class="codeType">DSPResource</span>),
<span class="codeType">ResourceTypeKind</span>.ComplexType,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">null</span>,
<span class="codeKeyword">this</span>.namespaceName, name,
<span class="codeKeyword">false</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;resourceType.CanReflectOnInstanceType = <span class="codeKeyword">false</span>;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this</span>.resourceTypes.Add(resourceType.FullName, resourceType);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> resourceType;</p>
<p>}</p>
<p>&nbsp;</p>
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
void</span> AddKeyProperty(<span class="codeType">ResourceType</span> 
resourceType, <span class="codeKeyword">string</span> name,
<span class="codeType">Type</span> propertyType)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this</span>.AddPrimitiveProperty(resourceType, name, propertyType,
<span class="codeKeyword">true</span>);</p>
<p>}</p>
<p>&nbsp;</p>
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
void</span> AddPrimitiveProperty(<span class="codeType">ResourceType</span> 
resourceType, <span class="codeKeyword">string</span> name,
<span class="codeType">Type</span> propertyType)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this</span>.AddPrimitiveProperty(resourceType, name, propertyType,
<span class="codeKeyword">false</span>);</p>
<p>}</p>
<p>&nbsp;</p>
<p><span class="codeKeyword">private</span> <span class="codeKeyword">
void</span> AddPrimitiveProperty(<span class="codeType">ResourceType</span> 
resourceType, <span class="codeKeyword">string</span> name,
<span class="codeType">Type</span> propertyType, <span class="codeKeyword">
bool</span> isKey)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceType</span> type = <span class="codeType">ResourceType</span>.GetPrimitiveResourceType(propertyType);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourcePropertyKind</span> kind = <span class="codeType">
ResourcePropertyKind</span>.Primitive;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (isKey)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;kind |= <span class="codeType">ResourcePropertyKind</span>.Key;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceProperty</span> property = <span class="codeKeyword">new</span>
<span class="codeType">ResourceProperty</span>(name, kind, type);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;property.CanReflectOnInstanceTypeProperty = <span class="codeKeyword">false</span>;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;resourceType.AddProperty(property);</p>
<p>}</p>
<p>&nbsp;</p>
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
void</span> AddComplexProperty(<span class="codeType">ResourceType</span> 
resourceType, <span class="codeKeyword">string</span> name,
<span class="codeType">ResourceType</span> complexType)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (complexType.ResourceTypeKind != <span class="codeType">
ResourceTypeKind</span>.ComplexType)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">throw</span> <span class="codeKeyword">new</span>
<span class="codeType">ArgumentException</span>(<span class="codeString">&quot;The 
specified type for the complex property is not a complex type.&quot;</span>);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">ResourceProperty</span> property = <span class="codeKeyword">new</span>
<span class="codeType">ResourceProperty</span>(name,
<span class="codeType">ResourcePropertyKind</span>.ComplexType, 
complexType);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;property.CanReflectOnInstanceTypeProperty = <span class="codeKeyword">false</span>;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;resourceType.AddProperty(property);</p>
<p>}</p>
</div>



<p>Setting these properties to <i>false </i>tell 
the WCF Data Services Framework that the declaring “type”—in these cases the
<i>Product </i>and
<i>Category </i>types described in the metadata, which are technically just 
wrappers for <i>Dictionary</i>—don’t directly 
have properties like “ID” and thus reflection can’t be employed.</p>
<p>To be more specific, when the framework gets a URI like
<i>~/Products(2)</i>, asking for a specific
<i>Products </i>instance using its ID, the query can’t just try to use an 
ID property like this:</p>

<div class="Code">
<p>from p in _queryProvider.GetQueryRootForResourceSet(products)
<br />
where p.ID == 2 <br />
select p;</p>
</div>

<p>because <i>ID </i>is not a property of <i>Dictionary</i>. Instead, the query has to 
look something like this:</p>

<div class="Code">
<p>from p in _queryProvider.GetQueryRootForResourceSet(products)
<br />
where ((int) DataServiceProviderMethods.GetValue(p,&quot;ID&quot;)) == 2<br />
select p;</p>
</div>

<p>which gives your query provider the opportunity to re-write the expression as:</p>
<div class="Code">
<p>from p in _queryProvider.GetQueryRootForResourceSet(products)
<br />
where ((int) p[&quot;ID&quot;]) == 2 <br />
select p;</p>
</div>

<p>which is something that LINQ to Objects can handle (or may be easier to 
translate into SQL).</p>

<p>Note that for all this, the implementation of the
<i>IDataServiceMetadataProvider </i>interface 
doesn’t change; everything here is really just an implementation detail.</p>


<h3>Queries in the UnTyped\RO Sample</h3>

<p>In addition to the basic changes in the DataServiceProvider 
project already mentioned above, there’s quite a bit of modified/added code in 
the untyped version as compare with the Typed\RO sample.</p>
<p>To set the context, let’s again go a little deeper into the 
whole query mechanism. As noted in Part 1, the WCF Data Services Framework uses 
LINQ expressions to describe the query it parses from a URI, giving an 
appropriate expression tree to the data provider to ultimately execute. In the 
strongly-typed provider case we saw earlier, we were able to get an
<i>IQueryable</i> directly from our data 
source’s CLR classes, which is to say, we took advantage of the built-in LINQ to 
Objects implementation of <i>IQueryable</i> 
that works with in-memory object.</p>
<p>In the untyped provider case, your underlying data source 
can be just about anything, and if you have a LINQ query provider around for 
that source, the work you have to do in the data provider is to patch up the 
LINQ expression that the data services framework gives you so it ties into the 
data source.</p>
<p>Put another way, when the framework parses a URI and 
creates an expression tree, it knows at different nodes in that expression tree 
that it needs the value of certain properties. With a strongly-typed provider, 
it can just use reflection (that is, <i>
resource.property</i>) to get the value. With an untyped provider, however, it 
must ask the provider to retrieve the value of such a property.</p>
<p>How that works involves a class in the framework called
<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.dataserviceprovidermethods(VS.100).aspx">
<i>DataServiceProviderMethods</i></a>. This 
class contains four static methods, <i>
GetValue, GetSequenceValue, Convert, and TypeIs</i>, but each one does nothing 
in itself but throw a “not implemented” exception. “So,” you ask, “what good is 
that?” Well, by itself, the class isn’t good for anything other than a source of 
placeholder methods, which is exactly how the framework uses it.</p>
<p>What happens is that at every node in the expression tree 
where the framework requires a value, sequence value, conversion, or a type 
comparison, it inserts a method call to one of the
<i>DataServiceProviderMethods</i> members. The provider is then expected to
<i>go through that expression</i> tree
<i>and patch up these methods with calls into 
the real data source that will return the necessary information </i>(see Figure 
8)<i>.</i> Only then can the expression tree 
be passed to an appropriate query provider and executed; otherwise exceptions 
will occur.</p>

<p align="center">
<img src="assets/Figure8.png" alt="Walking an expression tree to patch up DataServiceProviderMethods"/></p>
<p align="center">Figure 8: A custom 
untyped data provider must walk the LINQ expression tree 
generated by the WCF Data Services Framework and replace any calls 
to members of <i>DataServiceProviderMethods
</i>with calls to real methods in the data source.</p>
<p>&nbsp;</p>



<p>The code that does all this in the UnTyped\RO sample 
involves a number of distinct classes. The first one to look at is called
<i>DSPMethodTranslatingVisitor</i>, which, as 
its name suggests, is an agent that does some method patch-ups in an expression 
tree. What it is doing follows a general implementation pattern in LINQ that’s 
fully described in the
<a href="http://msdn.microsoft.com/en-us/library/bb546136.aspx">How to: Modify 
Expression Trees</a> topic on MSDN. The basic idea is that you walk the tree 
using what’s called an <i>Expression Visitor,
</i>the code for which is given in the
<a href="http://msdn.microsoft.com/en-us/library/bb882521.aspx">How to: 
Implement an Expression Tree Visitor</a> topic and found in the UnTyped\RO 
solution in DataServiceProvider/ExpressionVisitor.cs. (Note: the
<i>ExpressionVisitor</i> class has become a standard part of the .NET 
Framework version 4; a private implementation is only necessary for data 
services that target .NET Framework 3.5.)</p>
<p>Our <i>
DSPMethodTranslatingVisitor</i>, then, as you can see in the C# file by the same 
name, is a class derived from <i>
ExpressionVisitor </i>whose sole purpose is to find and patch up calls to 
members of <i>DataServiceProviderMethods</i>.
</p>

<div class="Code">
<p><span class="codeKeyword">internal</span>
<span class="codeKeyword">class</span> DSPMethodTranslatingVisitor : 
ExpressionVisitor</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">internal</span> <span class="codeKeyword">static</span>
<span class="codeKeyword">readonly</span> MethodInfo GetValueMethodInfo =
<span class="codeKeyword">typeof</span>(DataServiceProviderMethods).GetMethod(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeString">&quot;GetValue&quot;</span>,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BindingFlags.Static | BindingFlags.Public,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">null</span>,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">new</span> Type[] { <span class="codeKeyword">
typeof</span>(<span class="codeKeyword">object</span>), <span class="codeKeyword">
typeof</span>(ResourceProperty) },</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">null</span>);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">internal</span> <span class="codeKeyword">static</span>
<span class="codeKeyword">readonly</span> MethodInfo GetSequenceValueMethodInfo =
<span class="codeKeyword">typeof</span>(DataServiceProviderMethods).GetMethod(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeString">&quot;GetSequenceValue&quot;</span>,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BindingFlags.Static | BindingFlags.Public,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">null</span>,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">new</span> Type[] { <span class="codeKeyword">
typeof</span>(<span class="codeKeyword">object</span>), <span class="codeKeyword">
typeof</span>(ResourceProperty) },</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">null</span>);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">internal</span> <span class="codeKeyword">static</span>
<span class="codeKeyword">readonly</span> MethodInfo ConvertMethodInfo =
<span class="codeKeyword">typeof</span>(DataServiceProviderMethods).GetMethod(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeString">&quot;Convert&quot;</span>,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BindingFlags.Static | BindingFlags.Public);</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">internal</span> <span class="codeKeyword">static</span>
<span class="codeKeyword">readonly</span> MethodInfo TypeIsMethodInfo =
<span class="codeKeyword">typeof</span>(DataServiceProviderMethods).GetMethod(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeString">&quot;TypeIs&quot;</span>,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BindingFlags.Static | BindingFlags.Public);</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">static</span> Expression 
TranslateExpression(Expression expression)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DSPMethodTranslatingVisitor 
visitor = <span class="codeKeyword">new</span> DSPMethodTranslatingVisitor();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> visitor.Visit(expression);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">internal</span> <span class="codeKeyword">override</span> Expression 
VisitMethodCall(MethodCallExpression m)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">if</span> (m.Method == GetValueMethodInfo)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Arguments[0] - the resource to get property 
value of - we assume it&#39;s a DSPEntity</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Arguments[1] - the ResourceProperty to get 
value of</span></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Just call the 
targetResource.GetValue(resourceProperty.Name)</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> 
Expression.Call(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this</span>.Visit(m.Arguments[0]),</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">typeof</span>(DSPResource).GetMethod(<span class="codeType">&quot;GetValue&quot;</span>),</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Expression.Property(m.Arguments[1],
<span class="codeString">&quot;Name&quot;</span>));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">else</span> <span class="codeKeyword">if</span> 
(m.Method.IsGenericMethod &amp;&amp; m.Method.GetGenericMethodDefinition() == 
GetSequenceValueMethodInfo)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Arguments[0] - the resource to get property 
value of - we assume it&#39;s a DSPEntity</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Arguments[1] - the ResourceProperty to get 
value of</span></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Just call the 
targetResource.GetValue(resourceProperty.Name) and cast it to the right</span></p>
<p><span class="codeComment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// IEnumerable&lt;T&gt; (which is the return type of the GetSequenceMethod</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> Expression.Convert(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Expression.Call(</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">this</span>.Visit(m.Arguments[0]),</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">typeof</span>(DSPResource).GetMethod(<span class="codeType">&quot;GetValue&quot;</span>),</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Expression.Property(m.Arguments[1],
<span class="codeString">&quot;Name&quot;</span>)),</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.Method.ReturnType);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">else</span> <span class="codeKeyword">if</span> 
(m.Method == ConvertMethodInfo)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// All our resources are of the same underlying 
CLR type, so no need for conversion of the CLR type</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// and we don&#39;t have any specific action to 
take to convert the Resource Types either (as we</span></p>
<p><span class="codeComment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// access properties from a property bag). So get rid of the conversions 
as we don&#39;t need them</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this</span>.Visit(m.Arguments[0]);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">else</span> <span class="codeKeyword">if</span> 
(m.Method == TypeIsMethodInfo)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Arguments[0] - the resource to determine the 
type of - we assume it&#39;s a DSPEntity</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// Arguments[1] - the ResourceType to test for</span></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeComment">// We don&#39;t support type inheritance yet, so 
simple comparison is enough</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> 
Expression.Equal(Expression.Property(<span class="codeKeyword">this</span>.Visit(m.Arguments[0]),</p>
<p><span class="codeKeyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typeof</span>(DSPResource).GetProperty(<span class="codeString">&quot;ResourceType&quot;</span>)), 
m.Arguments[1]);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">base</span>.VisitMethodCall(m);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>}</p>
</div>

<p>All that’s going on here is that this class caches
<i>MethodInfo </i>for each of the four
<i>DataServiceProviderMethods </i>we care 
about. Then it overrides <i>
ExpressionVisitor.VisitMethodCall</i>, which is called every time a method call 
node is encountered when walking the expression tree. In response, we check if 
the method call in question matches one of the
<i>DataServiceProviderMethods</i>. If so, we 
then replace that method call (which again, just throws a not-implemented 
exception) with one in our own data source (<i>DSPResource</i>).</p>
<p>So now that we have the machine in place to do the 
patch-up, let’s see how it’s called upon to do the job. That happens through 
this chain of events:</p>

<p>1. The WCF Data Services Framework calls the implementation of <i>IDataServiceQueryProvider.GetQueryRootForResourceSet</i> which exists in 
our <i>DSPResourceQueryProvider</i> class.</p>
<p>2. That method calls <i>DSPLinqQueryProvider.CreateQuery </i>to 
generate the appropriate <i>IQueryable </i> instance.</p>
<div class="Code">
<p><span class="codeKeyword">public</span> 
System.Linq.<span class="codeType">IQueryable</span> 
GetQueryRootForResourceSet(<span class="codeType">ResourceSet</span> 
resourceSet)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeType">
DSPLinqQueryProvider</span>.CreateQuery(<span class="codeKeyword">this</span>.dataSource.GetResourceSetEntities(resourceSet.Name).AsQueryable());</p>
<p>}</p>
</div>

<p>3. The <i>DSPLinqQueryProvider</i> class is, in our implementation, just a wrapper for the 
LINQ to Objects query provider (the standard .NET implementation of
<i>IQueryable</i>), stored internally as the variable <i>underlyingQueryProvider</i>. 
Its static <i>CreateQuery</i> method (invoked 
above), simply asks LINQ to Objects for an expression and then wraps it in out 
own query class.</p>

<div class="Code">
<p><span class="codeKeyword">internal</span>
<span class="codeKeyword">class</span> <span class="codeType">DSPLinqQueryProvider 
</span>: <span class="codeType">IQueryProvider</span></p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">private</span> 
<span class="codeType">IQueryProvider</span> 
underlyingQueryProvider;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">static</span> 
<span class="codeType">IQueryable</span> CreateQuery(<span class="codeType">IQueryable 
</span>underlyingQuery)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">DSPLinqQueryProvider
</span>provider = <span class="codeKeyword">new</span> 
<span class="codeType">DSPLinqQueryProvider</span>(underlyingQuery.Provider);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> 
provider.CreateQuery(underlyingQuery.Expression);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<p>}</p>
</div>

<p>4. As is true with LINQ in general, a query isn’t 
executed until its results are actually enumerated. In the meantime, the WCF 
Data Services Framework will be calling other methods in the query provider to 
build the expression tree (nodes of which use our internal class
<i>DSPLinqQuery</i>); see the
<i>IQueryProvider.CreateQuery&lt;TElement&gt;</i> 
and <i>IQueryProvider.CreateQuery</i> methods 
in DSPLinqQueryProvider.cs.</p>

<p>5. When the query is finally executed, calls are generated to <em>
IQueryable.GetEnumerator. </em>In cases where a single result is returned, a call is 
generated to either <i>
IQueryProvider.Execute&lt;TResult&gt; </i>or <i>
IQueryProvider.Execute, </i>both of which are again in DSPLinqQueryProvider.cs:</p>

<div class="Code">
<p><span class="codeKeyword">public</span> <span class="codeType">TResult </span>Execute&lt;<span class="codeType">TResult</span>&gt;(<span class="codeType">Expression</span> 
expression)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;expression = <span class="codeKeyword">this</span>.ProcessExpression(expression);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this</span>.underlyingQueryProvider.Execute&lt;<span class="codeType">TResult</span>&gt;(expression);</p>
<p>}</p>
<p>&nbsp;</p>
<p><span class="codeKeyword">public</span> <span class="codeKeyword">
object</span> Execute(<span class="codeType">Expression</span> expression)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;expression = <span class="codeKeyword">this</span>.ProcessExpression(expression);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeKeyword">this</span>.underlyingQueryProvider.Execute(expression);</p>
<p>}</p>
</div>

<p>6. Both of these invoke the private method
<i>DSPLinqQueryProvider.ProcessExpression</i>, 
which in turn calls the static method <i>
DSPMethodTranslatingVisitor.ProcessExpression</i>:</p>

<div class="Code">
<p><span class="codeKeyword">private</span>
<span class="codeType">Expression</span> ProcessExpression(<span class="codeType">Expression</span> 
expression)</p>
<p>{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> <span class="codeType">DSPMethodTranslatingVisitor</span>.TranslateExpression(expression);</p>
<p>}</p>
</div>

<p>7. This method, then, creates an instance of
<i>DSPMethodTranslatingVisitor</i> and calls 
its <i>Visit</i> method to walk the tree, 
thereby patching up all the necessary method calls:</p>

<div class="Code">
<p>&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">public</span> <span class="codeKeyword">static</span> 
<span class="codeType">Expression </span>TranslateExpression(<span class="codeType">Expression 
</span>expression)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeType">DSPMethodTranslatingVisitor
</span>visitor = <span class="codeKeyword">new</span> 
<span class="codeType">DSPMethodTranslatingVisitor</span>();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="codeKeyword">return</span> visitor.Visit(expression);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}</p>
</div>

<p>8. Finally, the patched-up expression tree comes 
back to one of the Execute methods in step 5 above, which is then passed on to 
LINQ to Objects and executed against our in-memory data source.</p>



<p>Obviously, when you’re dealing with a data source that isn’t in memory, you’ll 
need to invoke a different LINQ query provider to do the deed if, in fact, you 
more or less follow the structure of this sample. But as you can see, the whole 
process is one of again patching up a LINQ expression tree with the appropriate 
methods into the data source, then executing that expression tree. You can, of 
course, execute that query in any number of ways that don’t involve LINQ at all, 
such as translating into SQL statements.</p>
<p>The bottom line is that LINQ is only being used here as the language for 
describing a query, and that’s where the required understanding and usage of 
LINQ ends. The real point is running queries against your data source, and when 
you can do that, you have a fully-operational read-only provider in hand.</p>

<h2>Part 5: Adding Insert, Update, and Delete Support to an Untyped Provider</h2>
<p>As with the delta between the Typed\RO and Typed\RW samples, the difference 
between UnTyped\RO and UnTyped\RW is the addition of an
<i>IDataServiceUpdateProvider</i> 
implementation, which is found in the latter’s 
DataServiceProvider/DSPUpdateProvider.cs file. Here the requirements and 
operation of this interface, especially in maintaining a change list that’s not 
applied until <i>
IDataServiceUpdateProvider.SaveChanges </i>is called, are completely identical 
since the contract of the interface is the same regardless of the data source. 
Again, the WCF Data Services Framework doesn’t care about the internal details 
of the provider, only about it fulfilling its part of the contract.</p>
<p>With that in mind, there’s little more to say about the UnTyped\RW sample as the only real differences from 
Typed\RW have to do with the 
underlying type system. As noted already, the strongly-typed provider sample 
uses distinct CLR classes in its backing store, whereas the untyped sample uses 
its generic <i>DSPResource/i> wrapper class. 
But in the end, these are just implementation details. The necessary structural 
understanding on the provider level is the same as what was already covered in 
Part 2.</p>

<h2>Going Further</h2>
<p>In this document we’ve explored the basic structure of a 
custom data service provider with both read-only and read-write variants and 
working with both typed and untyped data sources. We’ve also explored what it 
means to support relationships/associations/navigation properties.</p>
<p>Custom providers can also implement additional interfaces 
to support other features. For details on these and other matters, see the 
following links:</p>

<ul>
	<li>
	<a href="http://msdn.microsoft.com/en-us/library/ee960143(VS.100).aspx">Core 
	documentation for custom data service providers</a> on MSDN.</li>
	
	<li>
	<a href="http://msdn.microsoft.com/en-us/library/dd672591(VS.100).aspx">
	Documentation for built-in providers</a> on MSDN.</li>
	
	<li>Server-side paging: see
	<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataservicepagingprovider(VS.100).aspx">
	IDataServicePagingProvider</a> (MSDN) and
	<a href="http://blogs.msdn.com/astoriateam/archive/2009/03/19/ado-net-data-services-v1-5-ctp1-server-driven-paging.aspx">
	Server Driven Paging</a> on the Data Services team blog.</li>
	
	<li>Media streaming: see 
	<a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.idataservicestreamprovider(VS.100).aspx">
	IDataServiceStreamProvider</a> 
	(MSDN) and 
	<a href="http://msdn.microsoft.com/en-us/library/ee960144(VS.100).aspx">Streaming Data Provider</a> (MSDN).</li>

</ul>


</body>

</html>
